34 #include <core/dbus/message.h>
35 #include <core/dbus/object.h>
36 #include <core/dbus/types/object_path.h>
38 #include <core/posix/this_process.h>
49 core::Signal<void> the_empty_signal;
56 object(impl->access_service()->add_object_for_path(
57 dbus::traits::Service<
media::Service>::object_path())),
59 exported(impl->access_bus(), resolver)
61 object->install_method_handler<mpris::Service::CreateSession>(
65 std::placeholders::_1));
66 object->install_method_handler<mpris::Service::CreateFixedSession>(
70 std::placeholders::_1));
71 object->install_method_handler<mpris::Service::ResumeSession>(
75 std::placeholders::_1));
76 object->install_method_handler<mpris::Service::PauseOtherSessions>(
80 std::placeholders::_1));
85 static unsigned int session_counter = 0;
87 unsigned int current_session = session_counter++;
90 ss <<
"/core/ubuntu/media/Service/sessions/" << current_session;
99 dbus::types::ObjectPath op{session_info.first};
104 media::Player::Configuration config
109 impl->access_service()->add_object_for_path(op)
114 auto session =
impl->create_session(config);
116 bool inserted =
false;
117 std::tie(std::ignore, inserted)
121 throw std::runtime_error(
"Problem persisting session in session store.");
124 auto reply = dbus::Message::make_method_return(msg);
125 reply->writer() << op;
127 impl->access_bus()->send(reply);
128 }
catch(
const std::runtime_error& e)
130 auto reply = dbus::Message::make_error(
134 impl->access_bus()->send(reply);
146 msg->reader() >> name;
152 dbus::types::ObjectPath op{session_info.first};
155 media::Player::Configuration config
160 impl->access_service()->add_object_for_path(op)
163 auto session =
impl->create_session(config);
164 session->lifetime().set(media::Player::Lifetime::resumable);
166 bool inserted =
false;
167 std::tie(std::ignore, inserted)
171 throw std::runtime_error(
"Problem persisting session in session store.");
175 auto reply = dbus::Message::make_method_return(msg);
176 reply->writer() << op;
178 impl->access_bus()->send(reply);
184 auto reply = dbus::Message::make_error(
187 "Unable to locate player session");
188 impl->access_bus()->send(reply);
192 std::stringstream ss;
193 ss <<
"/core/ubuntu/media/Service/sessions/" << key;
194 dbus::types::ObjectPath op{ss.str()};
196 auto reply = dbus::Message::make_method_return(msg);
197 reply->writer() << op;
199 impl->access_bus()->send(reply);
201 }
catch(
const std::runtime_error& e)
203 auto reply = dbus::Message::make_error(
207 impl->access_bus()->send(reply);
219 msg->reader() >> key;
222 auto reply = dbus::Message::make_error(
225 "Unable to locate player session");
226 impl->access_bus()->send(reply);
230 std::stringstream ss;
231 ss <<
"/core/ubuntu/media/Service/sessions/" << key;
232 dbus::types::ObjectPath op{ss.str()};
234 auto reply = dbus::Message::make_method_return(msg);
235 reply->writer() << op;
237 impl->access_bus()->send(reply);
238 }
catch(
const std::runtime_error& e)
240 auto reply = dbus::Message::make_error(
244 impl->access_bus()->send(reply);
251 std::cout << __PRETTY_FUNCTION__ << std::endl;
253 msg->reader() >> key;
254 impl->pause_other_sessions(key);
256 auto reply = dbus::Message::make_method_return(msg);
257 impl->access_bus()->send(reply);
266 std::map<media::Player::PlayerKey, std::shared_ptr<media::Player>>
session_store;
275 defaults.
identity =
"core::media::Hub";
296 static const bool export_to_indicator_sound_via_mpris
298 core::posix::this_process::env::get(
"UBUNTU_MEDIA_HUB_EXPORT_TO_INDICATOR_VIA_MPRIS",
"0") ==
"1"
301 return export_to_indicator_sound_via_mpris ?
"org.mpris.MediaPlayer2.MediaHub" :
302 "hidden.org.mpris.MediaPlayer2.MediaHub";
308 object{
service->add_object_for_path(dbus::types::ObjectPath{
"/org/mpris/MediaPlayer2"})},
314 object->install_method_handler<core::dbus::interfaces::Properties::GetAll>([
this](
const core::dbus::Message::Ptr& msg)
317 std::string itf; msg->reader() >> itf;
318 core::dbus::Message::Ptr reply = core::dbus::Message::make_method_return(msg);
331 auto next = [
this](
const core::dbus::Message::Ptr& msg)
338 Exported::bus->send(core::dbus::Message::make_method_return(msg));
340 object->install_method_handler<mpris::Player::Next>(next);
342 auto previous = [
this](
const core::dbus::Message::Ptr& msg)
349 Exported::bus->send(core::dbus::Message::make_method_return(msg));
351 object->install_method_handler<mpris::Player::Previous>(previous);
353 auto pause = [
this](
const core::dbus::Message::Ptr& msg)
360 Exported::bus->send(core::dbus::Message::make_method_return(msg));
362 object->install_method_handler<mpris::Player::Pause>(pause);
364 auto stop = [
this](
const core::dbus::Message::Ptr& msg)
371 Exported::bus->send(core::dbus::Message::make_method_return(msg));
373 object->install_method_handler<mpris::Player::Stop>(
stop);
375 auto play = [
this](
const core::dbus::Message::Ptr& msg)
382 Exported::bus->send(core::dbus::Message::make_method_return(msg));
384 object->install_method_handler<mpris::Player::Play>(play);
386 auto play_pause = [
this](
const core::dbus::Message::Ptr& msg)
392 if (sp->playback_status() == media::Player::PlaybackStatus::playing)
394 else if (sp->playback_status() != media::Player::PlaybackStatus::null)
398 Exported::bus->send(core::dbus::Message::make_method_return(msg));
400 object->install_method_handler<mpris::Player::PlayPause>(play_pause);
414 connections.seeked_to = cp->seeked_to().connect([
this](std::uint64_t position)
419 connections.duration_changed = cp->duration().changed().connect([
this](std::uint64_t duration)
424 connections.position_changed = cp->position().changed().connect([
this](std::uint64_t position)
443 bool has_title = md.
count(xesam::Title::name) > 0;
444 bool has_album_name = md.
count(xesam::Album::name) > 0;
445 bool has_artist_name = md.
count(xesam::Artist::name) > 0;
448 dict[xesam::Title::name] = dbus::types::Variant::encode(md.
get(xesam::Title::name));
450 dict[xesam::Album::name] = dbus::types::Variant::encode(md.
get(xesam::Album::name));
452 dict[xesam::Artist::name] = dbus::types::Variant::encode(md.
get(xesam::Artist::name));
456 has_title ? md.
get(xesam::Title::name) :
"",
457 has_album_name ? md.
get(xesam::Album::name) :
"",
458 has_artist_name ? md.
get(xesam::Artist::name) :
""));
461 wrap[mpris::Player::Properties::Metadata::name()] = dbus::types::Variant::encode(dict);
465 dbus::traits::Service<mpris::Player::Properties::Metadata::Interface>::interface_name(),
467 std::vector<std::string>()));
510 the_empty_signal.connect([](){})
514 the_empty_signal.connect([](){})
518 the_empty_signal.connect([](){})
522 the_empty_signal.connect([](){})
526 the_empty_signal.connect([](){})
530 the_empty_signal.connect([](){})
548 return d->session_store.count(key) > 0;
553 return d->session_store.at(key);
558 for (
const auto& pair : d->session_store)
559 enumerator(pair.first, pair.second);
577 d->session_store.erase(key);
578 d->exported.unset_if_current(player);
580 for (
auto it: d->fixed_session_store) {
581 if (it.second == key) {
582 d->fixed_session_store.erase(it.first);
595 access_bus()->stop();
std::shared_ptr< core::dbus::Property< Properties::Duration > > duration
Properties::CanGoPrevious::ValueType can_go_previous
std::shared_ptr< core::dbus::Property< Properties::LoopStatus > > loop_status
static const std::string & name()
Properties::CanGoNext::ValueType can_go_next
static const char * from(core::ubuntu::media::Player::PlaybackStatus status)
struct mpris::Player::Skeleton::@14 properties
std::map< std::string, core::dbus::types::Variant > Dictionary
static const std::string & name()
static const char * from(core::ubuntu::media::Player::LoopStatus status)
std::map< std::string, core::dbus::types::Variant > get_all_properties()
void get_connection_app_armor_security_async(const std::string &name, std::function< void(const std::string &)> handler)
Dictionary get_all_properties()
struct mpris::Player::Skeleton::@15 signals
static const std::string & name()
core::dbus::Signal< Signals::Seeked, Signals::Seeked::ArgumentType >::Ptr seeked_to
std::shared_ptr< core::dbus::Property< Properties::PlaybackStatus > > playback_status
std::shared_ptr< core::dbus::Property< Properties::CanControl > > can_control
std::shared_ptr< core::dbus::Property< Properties::Position > > position
static const std::string & name()
dbus::Signal< core::dbus::interfaces::Properties::Signals::PropertiesChanged, core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType >::Ptr properties_changed
static const std::string & name()