Music Hub  ..
A session-wide music playback service
player_stub.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 <core/media/service.h>
21 #include <core/media/track_list.h>
23 
24 #include "codec.h"
25 #include "player_stub.h"
26 #include "player_traits.h"
27 #include "property_stub.h"
28 #include "the_session_bus.h"
29 #include "track_list_stub.h"
30 
31 #include "mpris/player.h"
32 
33 #include <core/dbus/property.h>
34 #include <core/dbus/types/object_path.h>
35 
36 #include <limits>
37 
38 #define UNUSED __attribute__((unused))
39 
40 namespace dbus = core::dbus;
41 namespace media = core::ubuntu::media;
42 
44 {
45  Private(const std::shared_ptr<Service>& parent,
46  const std::shared_ptr<core::dbus::Service>& service,
47  const std::shared_ptr<core::dbus::Object>& object,
48  const std::string& uuid
49  ) : parent(parent),
50  service(service),
51  object(object),
52  key(object->invoke_method_synchronously<mpris::Player::Key, media::Player::PlayerKey>().value()),
53  uuid(uuid),
56  {
57  // Link the properties from the server side to the client side over the bus
58  object->get_property<mpris::Player::Properties::CanPlay>(),
59  object->get_property<mpris::Player::Properties::CanPause>(),
60  object->get_property<mpris::Player::Properties::CanSeek>(),
61  object->get_property<mpris::Player::Properties::CanControl>(),
62  object->get_property<mpris::Player::Properties::CanGoNext>(),
63  object->get_property<mpris::Player::Properties::CanGoPrevious>(),
64  object->get_property<mpris::Player::Properties::IsVideoSource>(),
65  object->get_property<mpris::Player::Properties::IsAudioSource>(),
66  object->get_property<mpris::Player::Properties::TypedPlaybackStatus>(),
67  object->get_property<mpris::Player::Properties::TypedLoopStatus>(),
68  object->get_property<mpris::Player::Properties::PlaybackRate>(),
69  object->get_property<mpris::Player::Properties::Shuffle>(),
70  object->get_property<mpris::Player::Properties::TypedMetaData>(),
71  object->get_property<mpris::Player::Properties::Volume>(),
72  object->get_property<mpris::Player::Properties::Position>(),
73  object->get_property<mpris::Player::Properties::Duration>(),
74  object->get_property<mpris::Player::Properties::AudioStreamRole>(),
75  object->get_property<mpris::Player::Properties::Orientation>(),
76  object->get_property<mpris::Player::Properties::Lifetime>(),
77  object->get_property<mpris::Player::Properties::MinimumRate>(),
78  object->get_property<mpris::Player::Properties::MaximumRate>()
79  },
80  signals
81  {
82  object->get_signal<mpris::Player::Signals::Seeked>(),
83  object->get_signal<mpris::Player::Signals::AboutToFinish>(),
84  object->get_signal<mpris::Player::Signals::EndOfStream>(),
85  object->get_signal<mpris::Player::Signals::PlaybackStatusChanged>(),
86  object->get_signal<mpris::Player::Signals::VideoDimensionChanged>(),
87  object->get_signal<mpris::Player::Signals::Error>()
88  }
89  {
90  }
91 
93  {
94  }
95 
96  std::shared_ptr<Service> parent;
97  std::shared_ptr<TrackList> track_list;
98  dbus::Service::Ptr service;
99  dbus::Object::Ptr object;
101  std::string uuid;
103  struct
104  {
105  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanPlay>> can_play;
106  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanPause>> can_pause;
107  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanSeek>> can_seek;
108  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanControl>> can_control;
109  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanGoNext>> can_go_next;
110  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::CanGoPrevious>> can_go_previous;
111  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::IsVideoSource>> is_video_source;
112  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::IsAudioSource>> is_audio_source;
113 
114  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedPlaybackStatus>> playback_status;
115  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedLoopStatus>> loop_status;
116  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::PlaybackRate>> playback_rate;
117  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Shuffle>> shuffle;
118  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::TypedMetaData>> meta_data_for_current_track;
119  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Volume>> volume;
120  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Position>> position;
121  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Duration>> duration;
122  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::AudioStreamRole>> audio_role;
123  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Orientation>> orientation;
124  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::Lifetime>> lifetime;
125  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::MinimumRate>> minimum_playback_rate;
126  std::shared_ptr<core::dbus::Property<mpris::Player::Properties::MaximumRate>> maximum_playback_rate;
127  } properties;
128 
129  struct Signals
130  {
131  typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal;
132  typedef core::dbus::Signal<mpris::Player::Signals::AboutToFinish, mpris::Player::Signals::AboutToFinish::ArgumentType> DBusAboutToFinishSignal;
133  typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal;
134  typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal;
135  typedef core::dbus::Signal<mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType> DBusVideoDimensionChangedSignal;
136  typedef core::dbus::Signal<mpris::Player::Signals::Error, mpris::Player::Signals::Error::ArgumentType> DBusErrorSignal;
137 
138  Signals(const std::shared_ptr<DBusSeekedToSignal>& seeked,
139  const std::shared_ptr<DBusAboutToFinishSignal>& atf,
140  const std::shared_ptr<DBusEndOfStreamSignal>& eos,
141  const std::shared_ptr<DBusPlaybackStatusChangedSignal>& status,
142  const std::shared_ptr<DBusVideoDimensionChangedSignal>& d,
143  const std::shared_ptr<DBusErrorSignal>& e)
144  : seeked_to(),
145  about_to_finish(),
146  end_of_stream(),
149  error(),
150  dbus
151  {
152  seeked,
153  atf,
154  eos,
155  status,
156  d,
157  e
158  }
159  {
160  dbus.seeked_to->connect([this](std::uint64_t value)
161  {
162  std::cout << "SeekedTo signal arrived via the bus." << std::endl;
163  seeked_to(value);
164  });
165 
166  dbus.about_to_finish->connect([this]()
167  {
168  std::cout << "AboutToFinish signal arrived via the bus." << std::endl;
169  about_to_finish();
170  });
171 
172  dbus.end_of_stream->connect([this]()
173  {
174  std::cout << "EndOfStream signal arrived via the bus." << std::endl;
175  end_of_stream();
176  });
177 
178  dbus.playback_status_changed->connect([this](const media::Player::PlaybackStatus& status)
179  {
180  std::cout << "PlaybackStatusChanged signal arrived via the bus (Status: " << status << ")" << std::endl;
181  playback_status_changed(status);
182  });
183 
184  dbus.video_dimension_changed->connect([this](const media::video::Dimensions dimensions)
185  {
186  std::cout << "VideoDimensionChanged signal arrived via the bus." << std::endl;
187  video_dimension_changed(dimensions);
188  });
189 
190  dbus.error->connect([this](const media::Player::Error& e)
191  {
192  std::cout << "Error signal arrived via the bus (Error: " << e << ")" << std::endl;
193  error(e);
194  });
195  }
196 
197  core::Signal<int64_t> seeked_to;
198  core::Signal<void> about_to_finish;
199  core::Signal<void> end_of_stream;
200  core::Signal<media::Player::PlaybackStatus> playback_status_changed;
201  core::Signal<media::video::Dimensions> video_dimension_changed;
202  core::Signal<media::Player::Error> error;
203 
204  struct DBus
205  {
206  std::shared_ptr<DBusSeekedToSignal> seeked_to;
207  std::shared_ptr<DBusAboutToFinishSignal> about_to_finish;
208  std::shared_ptr<DBusEndOfStreamSignal> end_of_stream;
209  std::shared_ptr<DBusPlaybackStatusChangedSignal> playback_status_changed;
210  std::shared_ptr<DBusVideoDimensionChangedSignal> video_dimension_changed;
211  std::shared_ptr<DBusErrorSignal> error;
212  } dbus;
213  } signals;
214 };
215 
217  const std::shared_ptr<Service>& parent,
218  const std::shared_ptr<core::dbus::Service>& service,
219  const std::shared_ptr<core::dbus::Object>& object,
220  const std::string& uuid)
221  : d(new Private{parent, service, object, uuid})
222 {
223 }
224 
226 {
227 }
228 
229 std::string media::PlayerStub::uuid() const
230 {
231  return d->uuid;
232 }
233 
235 {
236  // No implementation
237 }
238 
240 {
241  // No implementation
242 }
243 
244 std::shared_ptr<media::TrackList> media::PlayerStub::track_list()
245 {
246  if (!d->track_list)
247  {
248  d->track_list = std::make_shared<media::TrackListStub>(
249  shared_from_this(),
250  d->service->object_for_path(
251  dbus::types::ObjectPath(
252  d->object->path().as_string() + "/TrackList")));
253  }
254  return d->track_list;
255 }
256 
258 {
259  return d->key;
260 }
261 
263 {
264  const auto op = d->object->transact_method<mpris::Player::OpenUri, bool>(uri);
265  if (op.is_error())
266  {
268  throw media::Player::Errors::InsufficientAppArmorPermissions{op.error().print()};
269  else if (op.error().name() == mpris::Player::Error::UriNotFound::name)
270  throw media::Player::Errors::UriNotFound{op.error().print()};
271  else
272  throw std::runtime_error{op.error().print()};
273  }
274 
275  return op.value();
276 }
277 
278 
279 bool media::PlayerStub::open_uri(const Track::UriType& uri, const Player::HeadersType& headers)
280 {
281  const auto op = d->object->transact_method<mpris::Player::OpenUriExtended, bool>(uri, headers);
282  if (op.is_error())
283  {
285  throw media::Player::Errors::InsufficientAppArmorPermissions{op.error().print()};
286  else
287  throw std::runtime_error{op.error().print()};
288  }
289 
290  return op.value();
291 }
292 
293 media::video::Sink::Ptr media::PlayerStub::create_gl_texture_video_sink(std::uint32_t texture_id)
294 {
295  auto op = d->object->transact_method<mpris::Player::CreateVideoSink, void>(texture_id);
296 
297  if (op.is_error())
298  {
300  throw media::Player::Errors::OutOfProcessBufferStreamingNotSupported{};
301  else
302  throw std::runtime_error{op.error().print()};
303  }
304 
305  return d->sink_factory(texture_id);
306 }
307 
309 {
310  auto op = d->object->transact_method<mpris::Player::Next, void>();
311 
312  if (op.is_error())
313  throw std::runtime_error("Problem switching to next track on remote object");
314 }
315 
317 {
318  auto op = d->object->transact_method<mpris::Player::Previous, void>();
319 
320  if (op.is_error())
321  throw std::runtime_error("Problem switching to previous track on remote object");
322 }
323 
325 {
326  auto op = d->object->transact_method<mpris::Player::Play, void>();
327 
328  if (op.is_error())
329  throw std::runtime_error("Problem starting playback on remote object");
330 }
331 
333 {
334  auto op = d->object->transact_method<mpris::Player::Pause, void>();
335 
336  if (op.is_error())
337  throw std::runtime_error("Problem pausing playback on remote object");
338 }
339 
340 void media::PlayerStub::seek_to(const std::chrono::microseconds& offset)
341 {
342  auto op = d->object->transact_method<mpris::Player::Seek, void, uint64_t>(offset.count());
343 
344  if (op.is_error())
345  throw std::runtime_error("Problem seeking on remote object");
346 }
347 
349 {
350  auto op = d->object->transact_method<mpris::Player::Stop, void>();
351 
352  if (op.is_error())
353  throw std::runtime_error("Problem stopping playback on remote object");
354 }
355 
356 const core::Property<bool>& media::PlayerStub::can_play() const
357 {
358  return *d->properties.can_play;
359 }
360 
361 const core::Property<bool>& media::PlayerStub::can_pause() const
362 {
363  return *d->properties.can_pause;
364 }
365 
366 const core::Property<bool>& media::PlayerStub::can_seek() const
367 {
368  return *d->properties.can_seek;
369 }
370 
371 const core::Property<bool>& media::PlayerStub::can_go_previous() const
372 {
373  return *d->properties.can_go_previous;
374 }
375 
376 const core::Property<bool>& media::PlayerStub::can_go_next() const
377 {
378  return *d->properties.can_go_next;
379 }
380 
381 const core::Property<bool>& media::PlayerStub::is_video_source() const
382 {
383  return *d->properties.is_video_source;
384 }
385 
386 const core::Property<bool>& media::PlayerStub::is_audio_source() const
387 {
388  return *d->properties.is_audio_source;
389 }
390 
391 const core::Property<media::Player::PlaybackStatus>& media::PlayerStub::playback_status() const
392 {
393  return *d->properties.playback_status;
394 }
395 
396 const core::Property<media::Player::LoopStatus>& media::PlayerStub::loop_status() const
397 {
398  return *d->properties.loop_status;
399 }
400 
401 const core::Property<media::Player::PlaybackRate>& media::PlayerStub::playback_rate() const
402 {
403  return *d->properties.playback_rate;
404 }
405 
406 const core::Property<bool>& media::PlayerStub::shuffle() const
407 {
408  return *d->properties.shuffle;
409 }
410 
411 const core::Property<media::Track::MetaData>& media::PlayerStub::meta_data_for_current_track() const
412 {
413  return *d->properties.meta_data_for_current_track;
414 }
415 
416 const core::Property<media::Player::Volume>& media::PlayerStub::volume() const
417 {
418  return *d->properties.volume;
419 }
420 
421 const core::Property<int64_t>& media::PlayerStub::position() const
422 {
423  return *d->properties.position;
424 }
425 
426 const core::Property<int64_t>& media::PlayerStub::duration() const
427 {
428  return *d->properties.duration;
429 }
430 
431 const core::Property<media::Player::AudioStreamRole>& media::PlayerStub::audio_stream_role() const
432 {
433  return *d->properties.audio_role;
434 }
435 
436 const core::Property<media::Player::Orientation>& media::PlayerStub::orientation() const
437 {
438  return *d->properties.orientation;
439 }
440 
441 const core::Property<media::Player::Lifetime>& media::PlayerStub::lifetime() const
442 {
443  return *d->properties.lifetime;
444 }
445 
446 const core::Property<media::Player::PlaybackRate>& media::PlayerStub::minimum_playback_rate() const
447 {
448  return *d->properties.minimum_playback_rate;
449 }
450 
451 const core::Property<media::Player::PlaybackRate>& media::PlayerStub::maximum_playback_rate() const
452 {
453  return *d->properties.maximum_playback_rate;
454 }
455 
456 core::Property<media::Player::LoopStatus>& media::PlayerStub::loop_status()
457 {
458  return *d->properties.loop_status;
459 }
460 
461 core::Property<media::Player::PlaybackRate>& media::PlayerStub::playback_rate()
462 {
463  return *d->properties.playback_rate;
464 }
465 
466 core::Property<bool>& media::PlayerStub::shuffle()
467 {
468  return *d->properties.shuffle;
469 }
470 
471 core::Property<media::Player::Volume>& media::PlayerStub::volume()
472 {
473  return *d->properties.volume;
474 }
475 
476 core::Property<media::Player::AudioStreamRole>& media::PlayerStub::audio_stream_role()
477 {
478  return *d->properties.audio_role;
479 }
480 
481 core::Property<media::Player::Lifetime>& media::PlayerStub::lifetime()
482 {
483  return *d->properties.lifetime;
484 }
485 
486 const core::Signal<int64_t>& media::PlayerStub::seeked_to() const
487 {
488  return d->signals.seeked_to;
489 }
490 
491 const core::Signal<void>& media::PlayerStub::about_to_finish() const
492 {
493  return d->signals.about_to_finish;
494 }
495 
496 const core::Signal<void>& media::PlayerStub::end_of_stream() const
497 {
498  return d->signals.end_of_stream;
499 }
500 
501 core::Signal<media::Player::PlaybackStatus>& media::PlayerStub::playback_status_changed()
502 {
503  return d->signals.playback_status_changed;
504 }
505 
506 const core::Signal<media::video::Dimensions>& media::PlayerStub::video_dimension_changed() const
507 {
508  return d->signals.video_dimension_changed;
509 }
510 
511 const core::Signal<media::Player::Error>& media::PlayerStub::error() const
512 {
513  return d->signals.error;
514 }
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanPlay > > can_play
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanControl > > can_control
std::shared_ptr< DBusEndOfStreamSignal > end_of_stream
std::shared_ptr< DBusVideoDimensionChangedSignal > video_dimension_changed
virtual video::Sink::Ptr create_gl_texture_video_sink(std::uint32_t texture_id)
SinkFactory make_platform_default_sink_factory(const Player::PlayerKey &key)
virtual const core::Property< bool > & shuffle() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::IsAudioSource > > is_audio_source
virtual const core::Property< int64_t > & position() const
std::tuple< Height, Width > Dimensions
Height and Width of a video.
Definition: dimensions.h:139
virtual const core::Property< Orientation > & orientation() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::MinimumRate > > minimum_playback_rate
virtual const core::Property< bool > & is_video_source() const
struct media::PlayerStub::Private::Signals signals
virtual const core::Signal< void > & end_of_stream() const
core::Signal< void > end_of_stream
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Lifetime > > lifetime
dbus::Object::Ptr object
Definition: player_stub.cpp:99
struct media::PlayerStub::Private::@21 properties
virtual const core::Property< int64_t > & duration() const
std::shared_ptr< DBusSeekedToSignal > seeked_to
virtual const core::Property< bool > & is_audio_source() const
core::dbus::Signal< mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType > DBusEndOfStreamSignal
std::map< std::string, std::string > HeadersType
Definition: player.h:49
std::shared_ptr< Service > parent
Definition: player_stub.cpp:96
core::dbus::Signal< mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType > DBusVideoDimensionChangedSignal
core::Signal< void > about_to_finish
virtual const core::Property< bool > & can_pause() const
core::Signal< media::video::Dimensions > video_dimension_changed
core::dbus::Signal< mpris::Player::Signals::Error, mpris::Player::Signals::Error::ArgumentType > DBusErrorSignal
virtual const core::Signal< video::Dimensions > & video_dimension_changed() const
virtual const core::Property< Volume > & volume() const
static constexpr const char * name
Definition: player.h:131
struct media::PlayerStub::Private::Signals::DBus dbus
virtual const core::Property< bool > & can_play() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Volume > > volume
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Shuffle > > shuffle
std::shared_ptr< DBusErrorSignal > error
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::TypedLoopStatus > > loop_status
media::video::SinkFactory sink_factory
std::shared_ptr< DBusAboutToFinishSignal > about_to_finish
virtual const core::Property< bool > & can_go_next() const
core::dbus::Signal< mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType > DBusSeekedToSignal
virtual const core::Property< Track::MetaData > & meta_data_for_current_track() const
core::dbus::Signal< mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType > DBusPlaybackStatusChangedSignal
core::dbus::Signal< mpris::Player::Signals::AboutToFinish, mpris::Player::Signals::AboutToFinish::ArgumentType > DBusAboutToFinishSignal
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanPause > > can_pause
Signals(const std::shared_ptr< DBusSeekedToSignal > &seeked, const std::shared_ptr< DBusAboutToFinishSignal > &atf, const std::shared_ptr< DBusEndOfStreamSignal > &eos, const std::shared_ptr< DBusPlaybackStatusChangedSignal > &status, const std::shared_ptr< DBusVideoDimensionChangedSignal > &d, const std::shared_ptr< DBusErrorSignal > &e)
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanGoPrevious > > can_go_previous
virtual core::Signal< PlaybackStatus > & playback_status_changed()
std::function< Sink::Ptr(std::uint32_t)> SinkFactory
virtual const core::Signal< void > & about_to_finish() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Duration > > duration
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::TypedMetaData > > meta_data_for_current_track
virtual const core::Signal< int64_t > & seeked_to() const
std::shared_ptr< TrackList > track_list
Definition: player_stub.cpp:97
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanSeek > > can_seek
virtual const core::Property< PlaybackStatus > & playback_status() const
virtual const core::Property< AudioStreamRole > & audio_stream_role() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::AudioStreamRole > > audio_role
virtual const core::Property< Lifetime > & lifetime() const
virtual PlayerKey key() const
core::Signal< media::Player::Error > error
virtual const core::Property< PlaybackRate > & minimum_playback_rate() const
virtual const core::Property< bool > & can_seek() const
dbus::Service::Ptr service
Definition: player_stub.cpp:98
virtual std::string uuid() const
virtual bool open_uri(const Track::UriType &uri)
std::string UriType
Definition: track.h:40
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Position > > position
core::Signal< int64_t > seeked_to
virtual void seek_to(const std::chrono::microseconds &offset)
Private(const std::shared_ptr< Service > &parent, const std::shared_ptr< core::dbus::Service > &service, const std::shared_ptr< core::dbus::Object > &object, const std::string &uuid)
Definition: player_stub.cpp:45
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::Orientation > > orientation
virtual const core::Signal< Error > & error() const
virtual std::shared_ptr< TrackList > track_list()
std::shared_ptr< DBusPlaybackStatusChangedSignal > playback_status_changed
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::TypedPlaybackStatus > > playback_status
virtual const core::Property< PlaybackRate > & playback_rate() const
virtual const core::Property< bool > & can_go_previous() const
virtual const core::Property< PlaybackRate > & maximum_playback_rate() const
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::PlaybackRate > > playback_rate
core::Signal< media::Player::PlaybackStatus > playback_status_changed
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::MaximumRate > > maximum_playback_rate
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::IsVideoSource > > is_video_source
std::shared_ptr< core::dbus::Property< mpris::Player::Properties::CanGoNext > > can_go_next
virtual const core::Property< LoopStatus > & loop_status() const
media::Player::PlayerKey key
PlayerStub(const std::shared_ptr< Service > &parent, const std::shared_ptr< core::dbus::Service > &service, const std::shared_ptr< core::dbus::Object > &object, const std::string &uuid=std::string{})