Music Hub ..
A session-wide music playback service
service_stub.cpp
Go to the documentation of this file.
1/*
2 * Copyright © 2013-2014 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 */
18
19#include "service_stub.h"
20#include "service_traits.h"
21
22#include "player_stub.h"
23#include "the_session_bus.h"
24
25#include "mpris/service.h"
26
28
29namespace dbus = core::dbus;
30namespace media = core::ubuntu::media;
31
34 object(
35 access_service()->object_for_path(
36 dbus::types::ObjectPath(
37 dbus::traits::Service<media::Service>::object_path()))
38 ),
39 daemon(the_session_bus()),
40 service_watcher_reg(
41 daemon.make_service_watcher(dbus::traits::Service<media::Service>::interface_name(),
42 dbus::DBus::WatchMode::registration)
43 ),
44 service_watcher_unreg(
45 daemon.make_service_watcher(dbus::traits::Service<media::Service>::interface_name(),
46 dbus::DBus::WatchMode::unregistration)
47 )
48{
49 auto bus = the_session_bus();
50 worker = std::move(std::thread([bus]()
51 {
52 bus->run();
53 }));
54
55 service_watcher_reg->service_registered().connect(
56 [&]()
57 {
58 MH_DEBUG("media-hub service registered");
59 signals.service_reconnected();
60 });
61 service_watcher_unreg->service_unregistered().connect(
62 [&]()
63 {
64 MH_DEBUG("media-hub service unregistered");
65 signals.service_disconnected();
66 });
67}
68
70{
71 auto bus = the_session_bus();
72 bus->stop();
73
74 if (worker.joinable())
75 worker.join();
76}
77
79{
80 const auto op = object->invoke_method_synchronously<mpris::Service::CreateSession,
81 std::tuple<dbus::types::ObjectPath, std::string>>();
82
83 if (op.is_error())
84 throw std::runtime_error("Problem creating session: " + op.error());
85
86 return std::shared_ptr<media::Player>(new media::PlayerStub
87 {
88 shared_from_this(),
89 access_service(),
90 access_service()->object_for_path(std::get<0>(op.value())),
91 std::get<1>(op.value())
92 });
93}
94
95void media::ServiceStub::detach_session(const std::string& uuid,
97{
98 const auto op = object->invoke_method_synchronously<mpris::Service::DetachSession,
99 void>(uuid);
100
101 if (op.is_error())
102 throw std::runtime_error("Problem detaching session: " + op.error());
103}
104
105std::shared_ptr<media::Player> media::ServiceStub::reattach_session(const std::string& uuid,
107{
108 const auto op = object->invoke_method_synchronously<mpris::Service::ReattachSession,
109 dbus::types::ObjectPath>(uuid);
110
111 if (op.is_error())
112 throw std::runtime_error("Problem reattaching session: " + op.error());
113
114 return std::shared_ptr<media::Player>(new media::PlayerStub
115 {
116 shared_from_this(),
117 access_service(),
118 access_service()->object_for_path(op.value()),
119 uuid
120 });
121}
122
123void media::ServiceStub::destroy_session(const std::string& uuid,
125{
126 const auto op = object->invoke_method_synchronously<mpris::Service::DestroySession,
127 void>(uuid);
128
129 if (op.is_error())
130 throw std::runtime_error("Problem destroying session: " + op.error());
131}
132
133std::shared_ptr<media::Player> media::ServiceStub::create_fixed_session(const std::string& name,
135{
136 const auto op = object->invoke_method_synchronously<mpris::Service::CreateFixedSession,
137 dbus::types::ObjectPath>(name);
138
139 if (op.is_error())
140 throw std::runtime_error("Problem creating session: " + op.error());
141
142 return std::shared_ptr<media::Player>(new media::PlayerStub
143 {
144 shared_from_this(),
145 access_service(),
146 access_service()->object_for_path(op.value())
147 });
148}
149
151{
152 const auto op = object->invoke_method_synchronously<mpris::Service::ResumeSession,
153 dbus::types::ObjectPath>(key);
154
155 if (op.is_error())
156 throw std::runtime_error("Problem resuming session: " + op.error());
157
158 return std::shared_ptr<media::Player>(new media::PlayerStub
159 {
160 shared_from_this(),
161 access_service(),
162 access_service()->object_for_path(op.value())
163 });
164}
165
167{
168 const auto op = object->invoke_method_synchronously<mpris::Service::PauseOtherSessions,
169 void>(key);
170
171 if (op.is_error())
172 throw std::runtime_error("Problem pausing other sessions: " + op.error());
173}
174
175const core::Signal<void>& media::ServiceStub::service_disconnected() const
176{
177 return signals.service_disconnected;
178}
179
180const core::Signal<void>& media::ServiceStub::service_reconnected() const
181{
182 return signals.service_reconnected;
183}
std::shared_ptr< Player > resume_session(Player::PlayerKey key)
void destroy_session(const std::string &uuid, const Player::Configuration &)
virtual const core::Signal< void > & service_disconnected() const
virtual const core::Signal< void > & service_reconnected() const
std::shared_ptr< Player > create_fixed_session(const std::string &name, const Player::Configuration &)
void detach_session(const std::string &uuid, const Player::Configuration &)
void pause_other_sessions(Player::PlayerKey key)
std::shared_ptr< Player > create_session(const Player::Configuration &)
std::shared_ptr< Player > reattach_session(const std::string &uuid, const Player::Configuration &)
#define MH_DEBUG(...)
Definition: logger.h:123
core::dbus::Bus::Ptr the_session_bus()
Definition: player.h:34