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 
29 namespace dbus = core::dbus;
30 namespace 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 
95 void 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 
105 std::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 
123 void 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 
133 std::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 
175 const core::Signal<void>& media::ServiceStub::service_disconnected() const
176 {
177  return signals.service_disconnected;
178 }
179 
180 const core::Signal<void>& media::ServiceStub::service_reconnected() const
181 {
182  return signals.service_reconnected;
183 }
std::shared_ptr< Player > resume_session(Player::PlayerKey key)
std::shared_ptr< Player > create_fixed_session(const std::string &name, const Player::Configuration &)
virtual const core::Signal< void > & service_reconnected() const
Definition: player.h:33
std::shared_ptr< Player > create_session(const Player::Configuration &)
virtual const core::Signal< void > & service_disconnected() const
#define MH_DEBUG(...)
Definition: logger.h:123
void pause_other_sessions(Player::PlayerKey key)
void detach_session(const std::string &uuid, const Player::Configuration &)
void destroy_session(const std::string &uuid, const Player::Configuration &)
core::dbus::Bus::Ptr the_session_bus()
std::shared_ptr< Player > reattach_session(const std::string &uuid, const Player::Configuration &)