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