Merge lp:~phablet-team/media-hub/mpris into lp:media-hub/stable
- mpris
- Merge into stable
Proposed by
Jim Hodapp
Status: | Merged |
---|---|
Approved by: | Alfonso Sanchez-Beato |
Approved revision: | 172 |
Merged at revision: | 159 |
Proposed branch: | lp:~phablet-team/media-hub/mpris |
Merge into: | lp:media-hub/stable |
Diff against target: |
528 lines (+117/-120) 14 files modified
CMakeLists.txt (+1/-1) README (+9/-0) debian/changelog (+10/-0) include/core/media/service.h (+3/-0) src/core/media/mpris/service.h (+1/-0) src/core/media/player_implementation.cpp (+4/-2) src/core/media/service_implementation.cpp (+5/-0) src/core/media/service_implementation.h (+1/-0) src/core/media/service_skeleton.cpp (+72/-113) src/core/media/service_skeleton.h (+1/-0) src/core/media/service_stub.cpp (+9/-1) src/core/media/service_stub.h (+1/-0) src/core/media/track_list_implementation.cpp (+0/-2) src/core/media/track_list_skeleton.cpp (+0/-1) |
To merge this branch: | bzr merge lp:~phablet-team/media-hub/mpris |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alfonso Sanchez-Beato | Approve | ||
Review via email: mp+269755@code.launchpad.net |
Commit message
Re-enable MPRIS player controls and improves background playlists.
Description of the change
Re-enable MPRIS player controls and improves background playlists.
To post a comment you must log in.
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) : | # |
review:
Approve
lp:~phablet-team/media-hub/mpris
updated
- 173. By Jim Hodapp
-
Make sure the correct player is set as the current player controled by MPRIS. Also improved the can_go_next() and can_go_previous() logic to always return true if the loop_status is currently set to loop over the entire playlist.
- 174. By Jim Hodapp
-
Bump version for change in interface
- 175. By Jim Hodapp
-
Merged with upstream
- 176. By Jim Hodapp
-
Bumped the package version.
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
review:
Needs Fixing
lp:~phablet-team/media-hub/mpris
updated
- 177. By Jim Hodapp
-
Added link to a coding standard for this code base and fixed line length in debian/changelog entry.
Revision history for this message
Jim Hodapp (jhodapp) wrote : | # |
Comments addressed.
lp:~phablet-team/media-hub/mpris
updated
- 178. By Jim Hodapp
-
Address code review comments
- 179. By Jim Hodapp
-
Addressed review comment - check for if (sp) is now moved into is_multimedia_
role()
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-04-10 16:21:16 +0000 | |||
3 | +++ CMakeLists.txt 2015-09-09 16:32:06 +0000 | |||
4 | @@ -3,7 +3,7 @@ | |||
5 | 3 | project(ubuntu-media-hub) | 3 | project(ubuntu-media-hub) |
6 | 4 | 4 | ||
7 | 5 | set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 3) | 5 | set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 3) |
9 | 6 | set(UBUNTU_MEDIA_HUB_VERSION_MINOR 1) | 6 | set(UBUNTU_MEDIA_HUB_VERSION_MINOR 2) |
10 | 7 | set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0) | 7 | set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0) |
11 | 8 | 8 | ||
12 | 9 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fPIC -pthread") | 9 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fPIC -pthread") |
13 | 10 | 10 | ||
14 | === modified file 'README' | |||
15 | --- README 2014-08-08 14:36:29 +0000 | |||
16 | +++ README 2015-09-09 16:32:06 +0000 | |||
17 | @@ -1,3 +1,12 @@ | |||
18 | 1 | Coding Convention: | ||
19 | 2 | ------------------ | ||
20 | 3 | |||
21 | 4 | NOTE: the media-hub code did not start out with the following coding convention, but it is being introduced to try and | ||
22 | 5 | converge on a standard from this point forward: | ||
23 | 6 | |||
24 | 7 | https://google-styleguide.googlecode.com/svn/trunk/cppguide.html | ||
25 | 8 | |||
26 | 9 | |||
27 | 1 | To Build: | 10 | To Build: |
28 | 2 | --------- | 11 | --------- |
29 | 3 | 12 | ||
30 | 4 | 13 | ||
31 | === modified file 'debian/changelog' | |||
32 | --- debian/changelog 2015-09-04 18:51:23 +0000 | |||
33 | +++ debian/changelog 2015-09-09 16:32:06 +0000 | |||
34 | @@ -1,3 +1,13 @@ | |||
35 | 1 | media-hub (3.2.0+15.04.20150904-0ubuntu1) UNRELEASED; urgency=medium | ||
36 | 2 | |||
37 | 3 | * Make sure the correct player is set as the current player controled by | ||
38 | 4 | MPRIS. | ||
39 | 5 | * Improved the can_go_next() and can_go_previous() logic to always return | ||
40 | 6 | true if the loop_status is currently set to loop over the entire | ||
41 | 7 | playlist. | ||
42 | 8 | |||
43 | 9 | -- phablet <phablet@ubuntu-phablet> Tue, 08 Sep 2015 17:18:15 -0400 | ||
44 | 10 | |||
45 | 1 | media-hub (3.1.0+15.04.20150904-0ubuntu1) vivid; urgency=medium | 11 | media-hub (3.1.0+15.04.20150904-0ubuntu1) vivid; urgency=medium |
46 | 2 | 12 | ||
47 | 3 | [ Alfonso Sanchez-Beato (email Canonical) ] | 13 | [ Alfonso Sanchez-Beato (email Canonical) ] |
48 | 4 | 14 | ||
49 | === modified file 'include/core/media/service.h' | |||
50 | --- include/core/media/service.h 2015-04-14 02:43:56 +0000 | |||
51 | +++ include/core/media/service.h 2015-09-09 16:32:06 +0000 | |||
52 | @@ -60,6 +60,9 @@ | |||
53 | 60 | /** @brief Resumes a fixed-name session directly by player key. */ | 60 | /** @brief Resumes a fixed-name session directly by player key. */ |
54 | 61 | virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0; | 61 | virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0; |
55 | 62 | 62 | ||
56 | 63 | /** @brief Sets the current player that the MPRIS interface will control */ | ||
57 | 64 | virtual void set_current_player(Player::PlayerKey) = 0; | ||
58 | 65 | |||
59 | 63 | /** @brief Pauses sessions other than the supplied one. */ | 66 | /** @brief Pauses sessions other than the supplied one. */ |
60 | 64 | virtual void pause_other_sessions(Player::PlayerKey) = 0; | 67 | virtual void pause_other_sessions(Player::PlayerKey) = 0; |
61 | 65 | 68 | ||
62 | 66 | 69 | ||
63 | === modified file 'src/core/media/mpris/service.h' | |||
64 | --- src/core/media/mpris/service.h 2015-04-10 16:13:55 +0000 | |||
65 | +++ src/core/media/mpris/service.h 2015-09-09 16:32:06 +0000 | |||
66 | @@ -115,6 +115,7 @@ | |||
67 | 115 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DestroySession, Service, 1000) | 115 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DestroySession, Service, 1000) |
68 | 116 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000) | 116 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000) |
69 | 117 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000) | 117 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000) |
70 | 118 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(SetCurrentPlayer, Service, 1000) | ||
71 | 118 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000) | 119 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000) |
72 | 119 | }; | 120 | }; |
73 | 120 | } | 121 | } |
74 | 121 | 122 | ||
75 | === modified file 'src/core/media/player_implementation.cpp' | |||
76 | --- src/core/media/player_implementation.cpp 2015-07-27 22:15:33 +0000 | |||
77 | +++ src/core/media/player_implementation.cpp 2015-09-09 16:32:06 +0000 | |||
78 | @@ -376,13 +376,15 @@ | |||
79 | 376 | 376 | ||
80 | 377 | std::function<bool()> can_go_next_getter = [this]() | 377 | std::function<bool()> can_go_next_getter = [this]() |
81 | 378 | { | 378 | { |
83 | 379 | return d->track_list->has_next(); | 379 | // If LoopStatus == playlist, then there is always a next track |
84 | 380 | return d->track_list->has_next() or Parent::loop_status() == Player::LoopStatus::playlist; | ||
85 | 380 | }; | 381 | }; |
86 | 381 | Parent::can_go_next().install(can_go_next_getter); | 382 | Parent::can_go_next().install(can_go_next_getter); |
87 | 382 | 383 | ||
88 | 383 | std::function<bool()> can_go_previous_getter = [this]() | 384 | std::function<bool()> can_go_previous_getter = [this]() |
89 | 384 | { | 385 | { |
91 | 385 | return d->track_list->has_previous(); | 386 | // If LoopStatus == playlist, then there is always a next previous |
92 | 387 | return d->track_list->has_previous() or Parent::loop_status() == Player::LoopStatus::playlist; | ||
93 | 386 | }; | 388 | }; |
94 | 387 | Parent::can_go_previous().install(can_go_previous_getter); | 389 | Parent::can_go_previous().install(can_go_previous_getter); |
95 | 388 | 390 | ||
96 | 389 | 391 | ||
97 | === modified file 'src/core/media/service_implementation.cpp' | |||
98 | --- src/core/media/service_implementation.cpp 2015-04-17 16:44:30 +0000 | |||
99 | +++ src/core/media/service_implementation.cpp 2015-09-09 16:32:06 +0000 | |||
100 | @@ -246,6 +246,11 @@ | |||
101 | 246 | return std::shared_ptr<media::Player>(); | 246 | return std::shared_ptr<media::Player>(); |
102 | 247 | } | 247 | } |
103 | 248 | 248 | ||
104 | 249 | void media::ServiceImplementation::set_current_player(Player::PlayerKey key) | ||
105 | 250 | { | ||
106 | 251 | // no impl | ||
107 | 252 | } | ||
108 | 253 | |||
109 | 249 | void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key) | 254 | void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key) |
110 | 250 | { | 255 | { |
111 | 251 | if (not d->configuration.player_store->has_player_for_key(key)) | 256 | if (not d->configuration.player_store->has_player_for_key(key)) |
112 | 252 | 257 | ||
113 | === modified file 'src/core/media/service_implementation.h' | |||
114 | --- src/core/media/service_implementation.h 2015-04-16 15:19:35 +0000 | |||
115 | +++ src/core/media/service_implementation.h 2015-09-09 16:32:06 +0000 | |||
116 | @@ -49,6 +49,7 @@ | |||
117 | 49 | void destroy_session(const std::string&, const Player::Configuration&); | 49 | void destroy_session(const std::string&, const Player::Configuration&); |
118 | 50 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); | 50 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); |
119 | 51 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); | 51 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); |
120 | 52 | void set_current_player(Player::PlayerKey key); | ||
121 | 52 | void pause_other_sessions(Player::PlayerKey key); | 53 | void pause_other_sessions(Player::PlayerKey key); |
122 | 53 | 54 | ||
123 | 54 | private: | 55 | private: |
124 | 55 | 56 | ||
125 | === modified file 'src/core/media/service_skeleton.cpp' | |||
126 | --- src/core/media/service_skeleton.cpp 2015-08-11 16:10:14 +0000 | |||
127 | +++ src/core/media/service_skeleton.cpp 2015-09-09 16:32:06 +0000 | |||
128 | @@ -91,6 +91,11 @@ | |||
129 | 91 | &Private::handle_resume_session, | 91 | &Private::handle_resume_session, |
130 | 92 | this, | 92 | this, |
131 | 93 | std::placeholders::_1)); | 93 | std::placeholders::_1)); |
132 | 94 | object->install_method_handler<mpris::Service::SetCurrentPlayer>( | ||
133 | 95 | std::bind( | ||
134 | 96 | &Private::handle_set_current_player, | ||
135 | 97 | this, | ||
136 | 98 | std::placeholders::_1)); | ||
137 | 94 | object->install_method_handler<mpris::Service::PauseOtherSessions>( | 99 | object->install_method_handler<mpris::Service::PauseOtherSessions>( |
138 | 95 | std::bind( | 100 | std::bind( |
139 | 96 | &Private::handle_pause_other_sessions, | 101 | &Private::handle_pause_other_sessions, |
140 | @@ -102,7 +107,7 @@ | |||
141 | 102 | { | 107 | { |
142 | 103 | static unsigned int session_counter = 0; | 108 | static unsigned int session_counter = 0; |
143 | 104 | 109 | ||
145 | 105 | unsigned int current_session = session_counter++; | 110 | const unsigned int current_session = session_counter++; |
146 | 106 | boost::uuids::uuid uuid = gen(); | 111 | boost::uuids::uuid uuid = gen(); |
147 | 107 | 112 | ||
148 | 108 | std::stringstream ss; | 113 | std::stringstream ss; |
149 | @@ -134,7 +139,8 @@ | |||
150 | 134 | configuration.player_store->add_player_for_key(key, impl->create_session(config)); | 139 | configuration.player_store->add_player_for_key(key, impl->create_session(config)); |
151 | 135 | uuid_player_map.insert(std::make_pair(uuid, key)); | 140 | uuid_player_map.insert(std::make_pair(uuid, key)); |
152 | 136 | 141 | ||
154 | 137 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, key, msg](const media::apparmor::ubuntu::Context& context) | 142 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), |
155 | 143 | [this, key, msg](const media::apparmor::ubuntu::Context& context) | ||
156 | 138 | { | 144 | { |
157 | 139 | fprintf(stderr, "%s():%d -- app_name='%s', attached\n", __func__, __LINE__, context.str().c_str()); | 145 | fprintf(stderr, "%s():%d -- app_name='%s', attached\n", __func__, __LINE__, context.str().c_str()); |
158 | 140 | player_owner_map.insert(std::make_pair(key, std::make_tuple(context.str(), true, msg->sender()))); | 146 | player_owner_map.insert(std::make_pair(key, std::make_tuple(context.str(), true, msg->sender()))); |
159 | @@ -213,7 +219,8 @@ | |||
160 | 213 | ss << "/core/ubuntu/media/Service/sessions/" << key; | 219 | ss << "/core/ubuntu/media/Service/sessions/" << key; |
161 | 214 | dbus::types::ObjectPath op{ss.str()}; | 220 | dbus::types::ObjectPath op{ss.str()}; |
162 | 215 | 221 | ||
164 | 216 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, msg, key, op](const media::apparmor::ubuntu::Context& context) | 222 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), |
165 | 223 | [this, msg, key, op](const media::apparmor::ubuntu::Context& context) | ||
166 | 217 | { | 224 | { |
167 | 218 | auto info = player_owner_map.at(key); | 225 | auto info = player_owner_map.at(key); |
168 | 219 | fprintf(stderr, "%s():%d -- reattach app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str()); | 226 | fprintf(stderr, "%s():%d -- reattach app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str()); |
169 | @@ -224,6 +231,12 @@ | |||
170 | 224 | // Signal player reconnection | 231 | // Signal player reconnection |
171 | 225 | auto player = configuration.player_store->player_for_key(key); | 232 | auto player = configuration.player_store->player_for_key(key); |
172 | 226 | player->reconnect(); | 233 | player->reconnect(); |
173 | 234 | // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video) | ||
174 | 235 | if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia) | ||
175 | 236 | { | ||
176 | 237 | std::cout << "Setting current_player" << std::endl; | ||
177 | 238 | exported.set_current_player(player); | ||
178 | 239 | } | ||
179 | 227 | 240 | ||
180 | 228 | auto reply = dbus::Message::make_method_return(msg); | 241 | auto reply = dbus::Message::make_method_return(msg); |
181 | 229 | reply->writer() << op; | 242 | reply->writer() << op; |
182 | @@ -280,7 +293,8 @@ | |||
183 | 280 | // the session is no longer usable. | 293 | // the session is no longer usable. |
184 | 281 | uuid_player_map.erase(uuid); | 294 | uuid_player_map.erase(uuid); |
185 | 282 | 295 | ||
187 | 283 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, msg, key](const media::apparmor::ubuntu::Context& context) | 296 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), |
188 | 297 | [this, msg, key](const media::apparmor::ubuntu::Context& context) | ||
189 | 284 | { | 298 | { |
190 | 285 | auto info = player_owner_map.at(key); | 299 | auto info = player_owner_map.at(key); |
191 | 286 | fprintf(stderr, "%s():%d -- Destroying app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str()); | 300 | fprintf(stderr, "%s():%d -- Destroying app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str()); |
192 | @@ -424,9 +438,18 @@ | |||
193 | 424 | } | 438 | } |
194 | 425 | } | 439 | } |
195 | 426 | 440 | ||
196 | 441 | void handle_set_current_player(const core::dbus::Message::Ptr& msg) | ||
197 | 442 | { | ||
198 | 443 | Player::PlayerKey key; | ||
199 | 444 | msg->reader() >> key; | ||
200 | 445 | impl->set_current_player(key); | ||
201 | 446 | |||
202 | 447 | auto reply = dbus::Message::make_method_return(msg); | ||
203 | 448 | impl->access_bus()->send(reply); | ||
204 | 449 | } | ||
205 | 450 | |||
206 | 427 | void handle_pause_other_sessions(const core::dbus::Message::Ptr& msg) | 451 | void handle_pause_other_sessions(const core::dbus::Message::Ptr& msg) |
207 | 428 | { | 452 | { |
208 | 429 | std::cout << __PRETTY_FUNCTION__ << std::endl; | ||
209 | 430 | Player::PlayerKey key; | 453 | Player::PlayerKey key; |
210 | 431 | msg->reader() >> key; | 454 | msg->reader() >> key; |
211 | 432 | impl->pause_other_sessions(key); | 455 | impl->pause_other_sessions(key); |
212 | @@ -477,20 +500,10 @@ | |||
213 | 477 | return defaults; | 500 | return defaults; |
214 | 478 | } | 501 | } |
215 | 479 | 502 | ||
216 | 480 | static std::string service_name() | ||
217 | 481 | { | ||
218 | 482 | static const bool export_to_indicator_sound_via_mpris | ||
219 | 483 | { | ||
220 | 484 | core::posix::this_process::env::get("UBUNTU_MEDIA_HUB_EXPORT_TO_INDICATOR_VIA_MPRIS", "0") == "1" | ||
221 | 485 | }; | ||
222 | 486 | |||
223 | 487 | return export_to_indicator_sound_via_mpris ? "org.mpris.MediaPlayer2.MediaHub" : | ||
224 | 488 | "hidden.org.mpris.MediaPlayer2.MediaHub"; | ||
225 | 489 | } | ||
226 | 490 | |||
227 | 491 | explicit Exported(const dbus::Bus::Ptr& bus, const media::CoverArtResolver& cover_art_resolver) | 503 | explicit Exported(const dbus::Bus::Ptr& bus, const media::CoverArtResolver& cover_art_resolver) |
228 | 492 | : bus{bus}, | 504 | : bus{bus}, |
230 | 493 | service{dbus::Service::add_service(bus, service_name())}, | 505 | /* Export MediaHub service interface on dbus */ |
231 | 506 | service{dbus::Service::add_service(bus, "org.mpris.MediaPlayer2.MediaHub")}, | ||
232 | 494 | object{service->add_object_for_path(dbus::types::ObjectPath{"/org/mpris/MediaPlayer2"})}, | 507 | object{service->add_object_for_path(dbus::types::ObjectPath{"/org/mpris/MediaPlayer2"})}, |
233 | 495 | media_player{mpris::MediaPlayer2::Skeleton::Configuration{bus, object, media_player_defaults()}}, | 508 | media_player{mpris::MediaPlayer2::Skeleton::Configuration{bus, object, media_player_defaults()}}, |
234 | 496 | player{mpris::Player::Skeleton::Configuration{bus, object, player_defaults()}}, | 509 | player{mpris::Player::Skeleton::Configuration{bus, object, player_defaults()}}, |
235 | @@ -500,14 +513,15 @@ | |||
236 | 500 | object->install_method_handler<core::dbus::interfaces::Properties::GetAll>([this](const core::dbus::Message::Ptr& msg) | 513 | object->install_method_handler<core::dbus::interfaces::Properties::GetAll>([this](const core::dbus::Message::Ptr& msg) |
237 | 501 | { | 514 | { |
238 | 502 | // Extract the interface | 515 | // Extract the interface |
240 | 503 | std::string itf; msg->reader() >> itf; | 516 | std::string interface; |
241 | 517 | msg->reader() >> interface; | ||
242 | 504 | core::dbus::Message::Ptr reply = core::dbus::Message::make_method_return(msg); | 518 | core::dbus::Message::Ptr reply = core::dbus::Message::make_method_return(msg); |
243 | 505 | 519 | ||
245 | 506 | if (itf == mpris::Player::name()) | 520 | if (interface == mpris::Player::name()) |
246 | 507 | reply->writer() << player.get_all_properties(); | 521 | reply->writer() << player.get_all_properties(); |
248 | 508 | else if (itf == mpris::MediaPlayer2::name()) | 522 | else if (interface == mpris::MediaPlayer2::name()) |
249 | 509 | reply->writer() << media_player.get_all_properties(); | 523 | reply->writer() << media_player.get_all_properties(); |
251 | 510 | else if (itf == mpris::Playlists::name()) | 524 | else if (interface == mpris::Playlists::name()) |
252 | 511 | reply->writer() << playlists.get_all_properties(); | 525 | reply->writer() << playlists.get_all_properties(); |
253 | 512 | 526 | ||
254 | 513 | Exported::bus->send(reply); | 527 | Exported::bus->send(reply); |
255 | @@ -516,9 +530,9 @@ | |||
256 | 516 | // Setup method handlers for mpris::Player methods. | 530 | // Setup method handlers for mpris::Player methods. |
257 | 517 | auto next = [this](const core::dbus::Message::Ptr& msg) | 531 | auto next = [this](const core::dbus::Message::Ptr& msg) |
258 | 518 | { | 532 | { |
260 | 519 | auto sp = current_player.lock(); | 533 | const auto sp = current_player.lock(); |
261 | 520 | 534 | ||
263 | 521 | if (sp) | 535 | if (is_multimedia_role()) |
264 | 522 | sp->next(); | 536 | sp->next(); |
265 | 523 | 537 | ||
266 | 524 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); | 538 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); |
267 | @@ -527,9 +541,9 @@ | |||
268 | 527 | 541 | ||
269 | 528 | auto previous = [this](const core::dbus::Message::Ptr& msg) | 542 | auto previous = [this](const core::dbus::Message::Ptr& msg) |
270 | 529 | { | 543 | { |
272 | 530 | auto sp = current_player.lock(); | 544 | const auto sp = current_player.lock(); |
273 | 531 | 545 | ||
275 | 532 | if (sp) | 546 | if (is_multimedia_role()) |
276 | 533 | sp->previous(); | 547 | sp->previous(); |
277 | 534 | 548 | ||
278 | 535 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); | 549 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); |
279 | @@ -538,9 +552,9 @@ | |||
280 | 538 | 552 | ||
281 | 539 | auto pause = [this](const core::dbus::Message::Ptr& msg) | 553 | auto pause = [this](const core::dbus::Message::Ptr& msg) |
282 | 540 | { | 554 | { |
284 | 541 | auto sp = current_player.lock(); | 555 | const auto sp = current_player.lock(); |
285 | 542 | 556 | ||
287 | 543 | if (sp) | 557 | if (is_multimedia_role() and sp->can_pause()) |
288 | 544 | sp->pause(); | 558 | sp->pause(); |
289 | 545 | 559 | ||
290 | 546 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); | 560 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); |
291 | @@ -549,9 +563,9 @@ | |||
292 | 549 | 563 | ||
293 | 550 | auto stop = [this](const core::dbus::Message::Ptr& msg) | 564 | auto stop = [this](const core::dbus::Message::Ptr& msg) |
294 | 551 | { | 565 | { |
296 | 552 | auto sp = current_player.lock(); | 566 | const auto sp = current_player.lock(); |
297 | 553 | 567 | ||
299 | 554 | if (sp) | 568 | if (is_multimedia_role()) |
300 | 555 | sp->stop(); | 569 | sp->stop(); |
301 | 556 | 570 | ||
302 | 557 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); | 571 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); |
303 | @@ -560,9 +574,9 @@ | |||
304 | 560 | 574 | ||
305 | 561 | auto play = [this](const core::dbus::Message::Ptr& msg) | 575 | auto play = [this](const core::dbus::Message::Ptr& msg) |
306 | 562 | { | 576 | { |
308 | 563 | auto sp = current_player.lock(); | 577 | const auto sp = current_player.lock(); |
309 | 564 | 578 | ||
311 | 565 | if (sp) | 579 | if (is_multimedia_role() and sp->can_play()) |
312 | 566 | sp->play(); | 580 | sp->play(); |
313 | 567 | 581 | ||
314 | 568 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); | 582 | Exported::bus->send(core::dbus::Message::make_method_return(msg)); |
315 | @@ -571,13 +585,15 @@ | |||
316 | 571 | 585 | ||
317 | 572 | auto play_pause = [this](const core::dbus::Message::Ptr& msg) | 586 | auto play_pause = [this](const core::dbus::Message::Ptr& msg) |
318 | 573 | { | 587 | { |
320 | 574 | auto sp = current_player.lock(); | 588 | const auto sp = current_player.lock(); |
321 | 575 | 589 | ||
323 | 576 | if (sp) | 590 | if (is_multimedia_role()) |
324 | 577 | { | 591 | { |
326 | 578 | if (sp->playback_status() == media::Player::PlaybackStatus::playing) | 592 | if (sp->playback_status() == media::Player::PlaybackStatus::playing |
327 | 593 | and sp->can_pause()) | ||
328 | 579 | sp->pause(); | 594 | sp->pause(); |
330 | 580 | else if (sp->playback_status() != media::Player::PlaybackStatus::null) | 595 | else if (sp->playback_status() != media::Player::PlaybackStatus::null |
331 | 596 | and sp->can_play()) | ||
332 | 581 | sp->play(); | 597 | sp->play(); |
333 | 582 | } | 598 | } |
334 | 583 | 599 | ||
335 | @@ -586,94 +602,29 @@ | |||
336 | 586 | object->install_method_handler<mpris::Player::PlayPause>(play_pause); | 602 | object->install_method_handler<mpris::Player::PlayPause>(play_pause); |
337 | 587 | } | 603 | } |
338 | 588 | 604 | ||
339 | 605 | inline bool is_multimedia_role() | ||
340 | 606 | { | ||
341 | 607 | const auto sp = current_player.lock(); | ||
342 | 608 | |||
343 | 609 | return (sp ? sp->audio_stream_role() == media::Player::AudioStreamRole::multimedia : false); | ||
344 | 610 | } | ||
345 | 611 | |||
346 | 589 | void set_current_player(const std::shared_ptr<media::Player>& cp) | 612 | void set_current_player(const std::shared_ptr<media::Player>& cp) |
347 | 590 | { | 613 | { |
350 | 591 | unset_current_player(); | 614 | std::cout << "*** " << __PRETTY_FUNCTION__ << std::endl; |
349 | 592 | |||
351 | 593 | // We will not keep the object alive. | 615 | // We will not keep the object alive. |
352 | 594 | current_player = cp; | 616 | current_player = cp; |
353 | 595 | 617 | ||
354 | 596 | // And announce that we can be controlled again. | 618 | // And announce that we can be controlled again. |
413 | 597 | player.properties.can_control->set(false); | 619 | player.properties.can_control->set(true); |
356 | 598 | |||
357 | 599 | // We wire up player state changes | ||
358 | 600 | connections.seeked_to = cp->seeked_to().connect([this](std::uint64_t position) | ||
359 | 601 | { | ||
360 | 602 | player.signals.seeked_to->emit(position); | ||
361 | 603 | }); | ||
362 | 604 | |||
363 | 605 | connections.duration_changed = cp->duration().changed().connect([this](std::uint64_t duration) | ||
364 | 606 | { | ||
365 | 607 | player.properties.duration->set(duration); | ||
366 | 608 | }); | ||
367 | 609 | |||
368 | 610 | connections.position_changed = cp->position().changed().connect([this](std::uint64_t position) | ||
369 | 611 | { | ||
370 | 612 | player.properties.position->set(position); | ||
371 | 613 | }); | ||
372 | 614 | |||
373 | 615 | connections.playback_status_changed = cp->playback_status().changed().connect([this](core::ubuntu::media::Player::PlaybackStatus status) | ||
374 | 616 | { | ||
375 | 617 | player.properties.playback_status->set(mpris::Player::PlaybackStatus::from(status)); | ||
376 | 618 | }); | ||
377 | 619 | |||
378 | 620 | connections.loop_status_changed = cp->loop_status().changed().connect([this](core::ubuntu::media::Player::LoopStatus status) | ||
379 | 621 | { | ||
380 | 622 | player.properties.loop_status->set(mpris::Player::LoopStatus::from(status)); | ||
381 | 623 | }); | ||
382 | 624 | |||
383 | 625 | connections.meta_data_changed = cp->meta_data_for_current_track().changed().connect([this](const core::ubuntu::media::Track::MetaData& md) | ||
384 | 626 | { | ||
385 | 627 | mpris::Player::Dictionary dict; | ||
386 | 628 | |||
387 | 629 | bool has_title = md.count(xesam::Title::name) > 0; | ||
388 | 630 | bool has_album_name = md.count(xesam::Album::name) > 0; | ||
389 | 631 | bool has_artist_name = md.count(xesam::Artist::name) > 0; | ||
390 | 632 | |||
391 | 633 | if (has_title) | ||
392 | 634 | dict[xesam::Title::name] = dbus::types::Variant::encode(md.get(xesam::Title::name)); | ||
393 | 635 | if (has_album_name) | ||
394 | 636 | dict[xesam::Album::name] = dbus::types::Variant::encode(md.get(xesam::Album::name)); | ||
395 | 637 | if (has_artist_name) | ||
396 | 638 | dict[xesam::Artist::name] = dbus::types::Variant::encode(md.get(xesam::Artist::name)); | ||
397 | 639 | |||
398 | 640 | dict[mpris::metadata::ArtUrl::name] = dbus::types::Variant::encode( | ||
399 | 641 | cover_art_resolver( | ||
400 | 642 | has_title ? md.get(xesam::Title::name) : "", | ||
401 | 643 | has_album_name ? md.get(xesam::Album::name) : "", | ||
402 | 644 | has_artist_name ? md.get(xesam::Artist::name) : "")); | ||
403 | 645 | |||
404 | 646 | mpris::Player::Dictionary wrap; | ||
405 | 647 | wrap[mpris::Player::Properties::Metadata::name()] = dbus::types::Variant::encode(dict); | ||
406 | 648 | |||
407 | 649 | player.signals.properties_changed->emit( | ||
408 | 650 | std::make_tuple( | ||
409 | 651 | dbus::traits::Service<mpris::Player::Properties::Metadata::Interface>::interface_name(), | ||
410 | 652 | wrap, | ||
411 | 653 | std::vector<std::string>())); | ||
412 | 654 | }); | ||
414 | 655 | } | 620 | } |
415 | 656 | 621 | ||
417 | 657 | void unset_current_player() | 622 | void reset_current_player() |
418 | 658 | { | 623 | { |
419 | 624 | std::cout << __PRETTY_FUNCTION__ << std::endl; | ||
420 | 625 | // And announce that we can no longer be controlled. | ||
421 | 626 | player.properties.can_control->set(false); | ||
422 | 659 | current_player.reset(); | 627 | current_player.reset(); |
423 | 660 | |||
424 | 661 | // We disconnect all previous event connections. | ||
425 | 662 | connections.seeked_to.disconnect(); | ||
426 | 663 | connections.duration_changed.disconnect(); | ||
427 | 664 | connections.position_changed.disconnect(); | ||
428 | 665 | connections.playback_status_changed.disconnect(); | ||
429 | 666 | connections.loop_status_changed.disconnect(); | ||
430 | 667 | connections.meta_data_changed.disconnect(); | ||
431 | 668 | |||
432 | 669 | // And announce that we cannot be controlled anymore. | ||
433 | 670 | player.properties.can_control->set(false); | ||
434 | 671 | } | ||
435 | 672 | |||
436 | 673 | void unset_if_current(const std::shared_ptr<media::Player>& cp) | ||
437 | 674 | { | ||
438 | 675 | if (cp == current_player.lock()) | ||
439 | 676 | unset_current_player(); | ||
440 | 677 | } | 628 | } |
441 | 678 | 629 | ||
442 | 679 | dbus::Bus::Ptr bus; | 630 | dbus::Bus::Ptr bus; |
443 | @@ -759,6 +710,14 @@ | |||
444 | 759 | return d->configuration.impl->resume_session(key); | 710 | return d->configuration.impl->resume_session(key); |
445 | 760 | } | 711 | } |
446 | 761 | 712 | ||
447 | 713 | void media::ServiceSkeleton::set_current_player(media::Player::PlayerKey key) | ||
448 | 714 | { | ||
449 | 715 | const auto player = d->configuration.player_store->player_for_key(key); | ||
450 | 716 | // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video) | ||
451 | 717 | if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia) | ||
452 | 718 | d->exported.set_current_player(player); | ||
453 | 719 | } | ||
454 | 720 | |||
455 | 762 | void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key) | 721 | void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key) |
456 | 763 | { | 722 | { |
457 | 764 | d->configuration.impl->pause_other_sessions(key); | 723 | d->configuration.impl->pause_other_sessions(key); |
458 | 765 | 724 | ||
459 | === modified file 'src/core/media/service_skeleton.h' | |||
460 | --- src/core/media/service_skeleton.h 2015-04-16 15:19:35 +0000 | |||
461 | +++ src/core/media/service_skeleton.h 2015-09-09 16:32:06 +0000 | |||
462 | @@ -59,6 +59,7 @@ | |||
463 | 59 | void destroy_session(const std::string&, const media::Player::Configuration&); | 59 | void destroy_session(const std::string&, const media::Player::Configuration&); |
464 | 60 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); | 60 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); |
465 | 61 | std::shared_ptr<Player> resume_session(Player::PlayerKey); | 61 | std::shared_ptr<Player> resume_session(Player::PlayerKey); |
466 | 62 | void set_current_player(Player::PlayerKey key); | ||
467 | 62 | void pause_other_sessions(Player::PlayerKey key); | 63 | void pause_other_sessions(Player::PlayerKey key); |
468 | 63 | 64 | ||
469 | 64 | void run(); | 65 | void run(); |
470 | 65 | 66 | ||
471 | === modified file 'src/core/media/service_stub.cpp' | |||
472 | --- src/core/media/service_stub.cpp 2015-04-17 16:44:30 +0000 | |||
473 | +++ src/core/media/service_stub.cpp 2015-09-09 16:32:06 +0000 | |||
474 | @@ -139,9 +139,17 @@ | |||
475 | 139 | }); | 139 | }); |
476 | 140 | } | 140 | } |
477 | 141 | 141 | ||
478 | 142 | void media::ServiceStub::set_current_player(Player::PlayerKey key) | ||
479 | 143 | { | ||
480 | 144 | auto op = d->object->invoke_method_synchronously<mpris::Service::SetCurrentPlayer, | ||
481 | 145 | void>(key); | ||
482 | 146 | |||
483 | 147 | if (op.is_error()) | ||
484 | 148 | throw std::runtime_error("Problem setting current player: " + op.error()); | ||
485 | 149 | } | ||
486 | 150 | |||
487 | 142 | void media::ServiceStub::pause_other_sessions(media::Player::PlayerKey key) | 151 | void media::ServiceStub::pause_other_sessions(media::Player::PlayerKey key) |
488 | 143 | { | 152 | { |
489 | 144 | std::cout << __PRETTY_FUNCTION__ << std::endl; | ||
490 | 145 | auto op = d->object->invoke_method_synchronously<mpris::Service::PauseOtherSessions, | 153 | auto op = d->object->invoke_method_synchronously<mpris::Service::PauseOtherSessions, |
491 | 146 | void>(key); | 154 | void>(key); |
492 | 147 | 155 | ||
493 | 148 | 156 | ||
494 | === modified file 'src/core/media/service_stub.h' | |||
495 | --- src/core/media/service_stub.h 2015-04-10 16:13:55 +0000 | |||
496 | +++ src/core/media/service_stub.h 2015-09-09 16:32:06 +0000 | |||
497 | @@ -45,6 +45,7 @@ | |||
498 | 45 | void destroy_session(const std::string& uuid, const Player::Configuration&); | 45 | void destroy_session(const std::string& uuid, const Player::Configuration&); |
499 | 46 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); | 46 | std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&); |
500 | 47 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); | 47 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); |
501 | 48 | void set_current_player(Player::PlayerKey key); | ||
502 | 48 | void pause_other_sessions(Player::PlayerKey key); | 49 | void pause_other_sessions(Player::PlayerKey key); |
503 | 49 | 50 | ||
504 | 50 | private: | 51 | private: |
505 | 51 | 52 | ||
506 | === modified file 'src/core/media/track_list_implementation.cpp' | |||
507 | --- src/core/media/track_list_implementation.cpp 2015-08-11 15:25:50 +0000 | |||
508 | +++ src/core/media/track_list_implementation.cpp 2015-09-09 16:32:06 +0000 | |||
509 | @@ -215,8 +215,6 @@ | |||
510 | 215 | 215 | ||
511 | 216 | void media::TrackListImplementation::reset() | 216 | void media::TrackListImplementation::reset() |
512 | 217 | { | 217 | { |
513 | 218 | std::cout << __PRETTY_FUNCTION__ << std::endl; | ||
514 | 219 | |||
515 | 220 | // Make sure playback stops | 218 | // Make sure playback stops |
516 | 221 | on_end_of_tracklist()(); | 219 | on_end_of_tracklist()(); |
517 | 222 | 220 | ||
518 | 223 | 221 | ||
519 | === modified file 'src/core/media/track_list_skeleton.cpp' | |||
520 | --- src/core/media/track_list_skeleton.cpp 2015-08-11 15:25:50 +0000 | |||
521 | +++ src/core/media/track_list_skeleton.cpp 2015-09-09 16:32:06 +0000 | |||
522 | @@ -521,7 +521,6 @@ | |||
523 | 521 | 521 | ||
524 | 522 | void media::TrackListSkeleton::reset() | 522 | void media::TrackListSkeleton::reset() |
525 | 523 | { | 523 | { |
526 | 524 | std::cout << __PRETTY_FUNCTION__ << std::endl; | ||
527 | 525 | d->current_track = d->empty_iterator; | 524 | d->current_track = d->empty_iterator; |
528 | 526 | } | 525 | } |
529 | 527 | 526 |
Some minor fixes required. A MP for trunk would be good too.