Merge lp:~phablet-team/media-hub/fix-1538703-take2 into lp:media-hub

Proposed by Jim Hodapp
Status: Merged
Approved by: Alfonso Sanchez-Beato
Approved revision: 200
Merged at revision: 180
Proposed branch: lp:~phablet-team/media-hub/fix-1538703-take2
Merge into: lp:media-hub
Diff against target: 702 lines (+205/-95)
16 files modified
CMakeLists.txt (+2/-2)
debian/changelog (+7/-0)
debian/libmedia-hub-doc.install (+1/-1)
doc/CMakeLists.txt (+2/-2)
include/core/media/service.h (+0/-3)
src/core/media/hashed_keyed_player_store.cpp (+1/-0)
src/core/media/mpris/service.h (+0/-1)
src/core/media/player_configuration.h (+3/-0)
src/core/media/player_implementation.cpp (+86/-6)
src/core/media/player_skeleton.h (+2/-0)
src/core/media/service_implementation.cpp (+5/-10)
src/core/media/service_implementation.h (+0/-1)
src/core/media/service_skeleton.cpp (+94/-59)
src/core/media/service_skeleton.h (+2/-0)
src/core/media/service_stub.cpp (+0/-9)
src/core/media/service_stub.h (+0/-1)
To merge this branch: bzr merge lp:~phablet-team/media-hub/fix-1538703-take2
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
PS Jenkins bot continuous-integration Approve
Konrad Zapałowicz (community) code Approve
Review via email: mp+292584@code.launchpad.net

Commit message

A rewrite of how the current player is set which is what the MPRIS control interface actively uses.

Description of the change

A rewrite of how the current player is set which is what the MPRIS control interface actively uses.

To post a comment you must log in.
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

Minor issue

review: Needs Fixing (code)
Revision history for this message
Jim Hodapp (jhodapp) :
199. By Jim Hodapp

Make sure to check if player_service is not nullptr before using it in is_current_player()

Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

LGTM

review: Approve (code)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Looks good, just curious why you had to remove the version dependency for libdbus-cpp-dev ?

review: Needs Information
200. By Jim Hodapp

Restore the libdbus-cpp-dev min version check

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-04-04 18:54:45 +0000
+++ CMakeLists.txt 2016-05-04 13:11:44 +0000
@@ -20,11 +20,11 @@
20 # we define the version to be 5.0.020 # we define the version to be 5.0.0
21 if (${DISTRO_CODENAME} STREQUAL "vivid")21 if (${DISTRO_CODENAME} STREQUAL "vivid")
22 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 4)22 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 4)
23 set(UBUNTU_MEDIA_HUB_VERSION_MINOR 1)23 set(UBUNTU_MEDIA_HUB_VERSION_MINOR 2)
24 set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0)24 set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0)
25 else ()25 else ()
26 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 5)26 set(UBUNTU_MEDIA_HUB_VERSION_MAJOR 5)
27 set(UBUNTU_MEDIA_HUB_VERSION_MINOR 0)27 set(UBUNTU_MEDIA_HUB_VERSION_MINOR 1)
28 set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0)28 set(UBUNTU_MEDIA_HUB_VERSION_PATCH 0)
29 endif()29 endif()
30endif()30endif()
3131
=== modified file 'debian/changelog'
--- debian/changelog 2016-04-07 02:00:40 +0000
+++ debian/changelog 2016-05-04 13:11:44 +0000
@@ -1,3 +1,10 @@
1media-hub (4.2.0+16.04.20160407.1-0ubuntu1) UNRELEASED; urgency=medium
2
3 * Improve the MPRIS player control interface so that it only
4 controls the last Player instance that called play().
5
6 -- Jim Hodapp <jim.hodapp@canonical.com> Tue, 03 May 2016 11:32:14 -0400
7
1media-hub (4.1.0+16.04.20160407.1-0ubuntu1) xenial; urgency=medium8media-hub (4.1.0+16.04.20160407.1-0ubuntu1) xenial; urgency=medium
29
3 * Add a proper logger to media-hub that includes traces, timestamps10 * Add a proper logger to media-hub that includes traces, timestamps
411
=== modified file 'debian/libmedia-hub-doc.install'
--- debian/libmedia-hub-doc.install 2014-03-06 22:51:51 +0000
+++ debian/libmedia-hub-doc.install 2016-05-04 13:11:44 +0000
@@ -1,1 +1,1 @@
1usr/share/doc/music-hub/html1usr/share/doc/media-hub/html
22
=== modified file 'doc/CMakeLists.txt'
--- doc/CMakeLists.txt 2013-08-14 18:05:23 +0000
+++ doc/CMakeLists.txt 2016-05-04 13:11:44 +0000
@@ -26,5 +26,5 @@
26 COMMENT "Generating API documentation with Doxygen" VERBATIM)26 COMMENT "Generating API documentation with Doxygen" VERBATIM)
27 install(27 install(
28 DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html28 DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
29 DESTINATION share/doc/music-hub)
30endif(DOXYGEN_FOUND)
31\ No newline at end of file29\ No newline at end of file
30 DESTINATION share/doc/media-hub)
31endif(DOXYGEN_FOUND)
3232
=== modified file 'include/core/media/service.h'
--- include/core/media/service.h 2015-09-08 20:03:56 +0000
+++ include/core/media/service.h 2016-05-04 13:11:44 +0000
@@ -60,9 +60,6 @@
60 /** @brief Resumes a fixed-name session directly by player key. */60 /** @brief Resumes a fixed-name session directly by player key. */
61 virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0;61 virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0;
6262
63 /** @brief Sets the current player that the MPRIS interface will control */
64 virtual void set_current_player(Player::PlayerKey) = 0;
65
66 /** @brief Pauses sessions other than the supplied one. */63 /** @brief Pauses sessions other than the supplied one. */
67 virtual void pause_other_sessions(Player::PlayerKey) = 0;64 virtual void pause_other_sessions(Player::PlayerKey) = 0;
6865
6966
=== modified file 'src/core/media/hashed_keyed_player_store.cpp'
--- src/core/media/hashed_keyed_player_store.cpp 2016-03-07 14:51:01 +0000
+++ src/core/media/hashed_keyed_player_store.cpp 2016-05-04 13:11:44 +0000
@@ -64,6 +64,7 @@
64void media::HashedKeyedPlayerStore::remove_player_for_key(const media::Player::PlayerKey& key)64void media::HashedKeyedPlayerStore::remove_player_for_key(const media::Player::PlayerKey& key)
65{65{
66 std::lock_guard<std::recursive_mutex> lg{guard};66 std::lock_guard<std::recursive_mutex> lg{guard};
67
67 auto it = map.find(key);68 auto it = map.find(key);
68 if (it != map.end())69 if (it != map.end())
69 {70 {
7071
=== modified file 'src/core/media/mpris/service.h'
--- src/core/media/mpris/service.h 2016-01-04 08:30:35 +0000
+++ src/core/media/mpris/service.h 2016-05-04 13:11:44 +0000
@@ -127,7 +127,6 @@
127 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DestroySession, Service, 1000)127 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DestroySession, Service, 1000)
128 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000)128 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000)
129 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000)129 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000)
130 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(SetCurrentPlayer, Service, 1000)
131 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000)130 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000)
132};131};
133}132}
134133
=== modified file 'src/core/media/player_configuration.h'
--- src/core/media/player_configuration.h 2015-04-17 16:44:30 +0000
+++ src/core/media/player_configuration.h 2016-05-04 13:11:44 +0000
@@ -19,6 +19,7 @@
19#define CORE_UBUNTU_MEDIA_PLAYER_CLIENT_CONFIGURATION_H_19#define CORE_UBUNTU_MEDIA_PLAYER_CLIENT_CONFIGURATION_H_
2020
21#include <core/media/player.h>21#include <core/media/player.h>
22#include <core/media/service.h>
2223
23#include <core/dbus/bus.h>24#include <core/dbus/bus.h>
24#include <core/dbus/object.h>25#include <core/dbus/object.h>
@@ -35,6 +36,8 @@
35 std::shared_ptr<core::dbus::Service> service;36 std::shared_ptr<core::dbus::Service> service;
36 // The actual session object representing a player instance.37 // The actual session object representing a player instance.
37 std::shared_ptr<core::dbus::Object> session;38 std::shared_ptr<core::dbus::Object> session;
39 // The Service instance that manages Player instances
40 core::ubuntu::media::Service* player_service;
38};41};
3942
40#endif // CORE_UBUNTU_MEDIA_PLAYER_CLIENT_CONFIGURATION_H_43#endif // CORE_UBUNTU_MEDIA_PLAYER_CLIENT_CONFIGURATION_H_
4144
=== modified file 'src/core/media/player_implementation.cpp'
--- src/core/media/player_implementation.cpp 2016-04-06 15:28:29 +0000
+++ src/core/media/player_implementation.cpp 2016-05-04 13:11:44 +0000
@@ -17,7 +17,10 @@
17 * Jim Hodapp <jim.hodapp@canonical.com>17 * Jim Hodapp <jim.hodapp@canonical.com>
18 */18 */
1919
20#include <core/media/service.h>
21
20#include "player_implementation.h"22#include "player_implementation.h"
23#include "service_skeleton.h"
21#include "util/timeout.h"24#include "util/timeout.h"
2225
23#include <unistd.h>26#include <unistd.h>
@@ -301,14 +304,14 @@
301 }304 }
302 }305 }
303306
304 void update_mpris_properties(void)307 void update_mpris_properties()
305 {308 {
306 bool has_previous = track_list->has_previous()309 const bool has_previous = track_list->has_previous()
307 or parent->Parent::loop_status() != Player::LoopStatus::none;310 or parent->Parent::loop_status() != Player::LoopStatus::none;
308 bool has_next = track_list->has_next()311 const bool has_next = track_list->has_next()
309 or parent->Parent::loop_status() != Player::LoopStatus::none;312 or parent->Parent::loop_status() != Player::LoopStatus::none;
310 auto n_tracks = track_list->tracks()->size();313 const auto n_tracks = track_list->tracks()->size();
311 bool has_tracks = (n_tracks > 0) ? true : false;314 const bool has_tracks = (n_tracks > 0) ? true : false;
312315
313 MH_INFO("Updating MPRIS TrackList properties:");316 MH_INFO("Updating MPRIS TrackList properties:");
314 MH_INFO("\tTracks: %d", n_tracks);317 MH_INFO("\tTracks: %d", n_tracks);
@@ -322,6 +325,58 @@
322 parent->can_go_next().set(has_next);325 parent->can_go_next().set(has_next);
323 }326 }
324327
328 bool pause_other_players(media::Player::PlayerKey key)
329 {
330 if (not config.parent.player_service)
331 return false;
332
333 media::ServiceSkeleton* skel {
334 reinterpret_cast<media::ServiceSkeleton*>(config.parent.player_service)
335 };
336 skel->pause_other_sessions(key);
337 return true;
338 }
339
340 bool update_current_player(media::Player::PlayerKey key)
341 {
342 if (not config.parent.player_service)
343 return false;
344
345 media::ServiceSkeleton* skel {
346 reinterpret_cast<media::ServiceSkeleton*>(config.parent.player_service)
347 };
348 skel->set_current_player(key);
349 return true;
350 }
351
352 bool is_current_player() const
353 {
354 if (not config.parent.player_service)
355 return false;
356
357 media::ServiceSkeleton* skel {
358 reinterpret_cast<media::ServiceSkeleton*>(config.parent.player_service)
359 };
360 return skel->is_current_player(parent->key());
361 }
362
363 bool is_multimedia_role() const
364 {
365 return parent->audio_stream_role() == media::Player::AudioStreamRole::multimedia;
366 }
367
368 bool reset_current_player()
369 {
370 if (not config.parent.player_service)
371 return false;
372
373 media::ServiceSkeleton* skel {
374 reinterpret_cast<media::ServiceSkeleton*>(config.parent.player_service)
375 };
376 skel->reset_current_player();
377 return true;
378 }
379
325 // Our link back to our parent.380 // Our link back to our parent.
326 media::PlayerImplementation<Parent>* parent;381 media::PlayerImplementation<Parent>* parent;
327 // We just store the parameters passed on construction.382 // We just store the parameters passed on construction.
@@ -478,6 +533,16 @@
478 // are cleared533 // are cleared
479 d->clear_wakelocks();534 d->clear_wakelocks();
480 d->track_list->reset();535 d->track_list->reset();
536
537 // This is not a fatal error but merely a warning that should
538 // be logged
539 if (d->is_multimedia_role() and d->is_current_player())
540 {
541 MH_DEBUG("==== Resetting current player");
542 if (not d->reset_current_player())
543 MH_WARNING("Failed to reset current player");
544 }
545
481 // And tell the outside world that the client has gone away546 // And tell the outside world that the client has gone away
482 d->on_client_disconnected();547 d->on_client_disconnected();
483 });548 });
@@ -687,7 +752,8 @@
687 d->track_list->reset();752 d->track_list->reset();
688753
689 // If empty uri, give the same meaning as QMediaPlayer::setMedia("")754 // If empty uri, give the same meaning as QMediaPlayer::setMedia("")
690 if (uri.empty()) {755 if (uri.empty())
756 {
691 MH_DEBUG("Resetting current media");757 MH_DEBUG("Resetting current media");
692 return true;758 return true;
693 }759 }
@@ -697,6 +763,7 @@
697 // Don't set new track as the current track to play since we're calling open_resource_for_uri above763 // Don't set new track as the current track to play since we're calling open_resource_for_uri above
698 static const bool make_current = false;764 static const bool make_current = false;
699 d->track_list->add_track_with_uri_at(uri, media::TrackList::after_empty_track(), make_current);765 d->track_list->add_track_with_uri_at(uri, media::TrackList::after_empty_track(), make_current);
766
700 return ret;767 return ret;
701}768}
702769
@@ -722,6 +789,19 @@
722void media::PlayerImplementation<Parent>::play()789void media::PlayerImplementation<Parent>::play()
723{790{
724 MH_TRACE("");791 MH_TRACE("");
792 if (d->is_multimedia_role())
793 {
794 MH_DEBUG("==== Pausing all other multimedia player sessions");
795 if (not d->pause_other_players(d->config.key))
796 MH_WARNING("Failed to pause other player sessions");
797
798 MH_DEBUG("==== Updating the current player");
799 // This player will begin playing so make sure it's the current player. If
800 // this operation fails it is not a fatal condition but should be logged
801 if (not d->update_current_player(d->config.key))
802 MH_WARNING("Failed to update current player");
803 }
804
725 d->engine->play();805 d->engine->play();
726}806}
727807
728808
=== modified file 'src/core/media/player_skeleton.h'
--- src/core/media/player_skeleton.h 2015-04-17 15:13:56 +0000
+++ src/core/media/player_skeleton.h 2016-05-04 13:11:44 +0000
@@ -57,6 +57,8 @@
57 std::shared_ptr<core::dbus::Service> service;57 std::shared_ptr<core::dbus::Service> service;
58 // The session object that we want to expose the skeleton upon.58 // The session object that we want to expose the skeleton upon.
59 std::shared_ptr<core::dbus::Object> session;59 std::shared_ptr<core::dbus::Object> session;
60 // The Service instance that manages Player instances
61 core::ubuntu::media::Service* player_service;
60 // Our functional dependencies.62 // Our functional dependencies.
61 apparmor::ubuntu::RequestContextResolver::Ptr request_context_resolver;63 apparmor::ubuntu::RequestContextResolver::Ptr request_context_resolver;
62 apparmor::ubuntu::RequestAuthenticator::Ptr request_authenticator;64 apparmor::ubuntu::RequestAuthenticator::Ptr request_authenticator;
6365
=== modified file 'src/core/media/service_implementation.cpp'
--- src/core/media/service_implementation.cpp 2016-04-05 19:27:50 +0000
+++ src/core/media/service_implementation.cpp 2016-05-04 13:11:44 +0000
@@ -186,11 +186,13 @@
186 auto player = std::make_shared<media::PlayerImplementation<media::PlayerSkeleton>>186 auto player = std::make_shared<media::PlayerImplementation<media::PlayerSkeleton>>
187 (media::PlayerImplementation<media::PlayerSkeleton>::Configuration187 (media::PlayerImplementation<media::PlayerSkeleton>::Configuration
188 {188 {
189 // Derive a PlayerSkeleton-specific Configuration based on Player::Configuration
189 media::PlayerSkeleton::Configuration190 media::PlayerSkeleton::Configuration
190 {191 {
191 conf.bus,192 conf.bus,
192 conf.service,193 conf.service,
193 conf.session,194 conf.session,
195 conf.player_service,
194 d->request_context_resolver,196 d->request_context_resolver,
195 d->request_authenticator197 d->request_authenticator
196 },198 },
@@ -258,11 +260,6 @@
258 return std::shared_ptr<media::Player>();260 return std::shared_ptr<media::Player>();
259}261}
260262
261void media::ServiceImplementation::set_current_player(Player::PlayerKey)
262{
263 // no impl
264}
265
266void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)263void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)
267{264{
268 MH_TRACE("");265 MH_TRACE("");
@@ -276,11 +273,9 @@
276 const std::shared_ptr<media::Player> current_player =273 const std::shared_ptr<media::Player> current_player =
277 d->configuration.player_store->player_for_key(key);274 d->configuration.player_store->player_for_key(key);
278275
279 // We immediately make the player known as new current player.276 d->configuration.player_store->enumerate_players([current_player, key]
280 if (current_player->audio_stream_role() == media::Player::multimedia)277 (const media::Player::PlayerKey& other_key,
281 d->configuration.player_store->set_current_player_for_key(key);278 const std::shared_ptr<media::Player>& other_player)
282
283 d->configuration.player_store->enumerate_players([current_player, key](const media::Player::PlayerKey& other_key, const std::shared_ptr<media::Player>& other_player)
284 {279 {
285 // Only pause a Player if all of the following criteria are met:280 // Only pause a Player if all of the following criteria are met:
286 // 1) currently playing281 // 1) currently playing
287282
=== modified file 'src/core/media/service_implementation.h'
--- src/core/media/service_implementation.h 2015-09-08 20:03:56 +0000
+++ src/core/media/service_implementation.h 2016-05-04 13:11:44 +0000
@@ -49,7 +49,6 @@
49 void destroy_session(const std::string&, const Player::Configuration&);49 void destroy_session(const std::string&, const Player::Configuration&);
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&);
51 std::shared_ptr<Player> resume_session(Player::PlayerKey key);51 std::shared_ptr<Player> resume_session(Player::PlayerKey key);
52 void set_current_player(Player::PlayerKey key);
53 void pause_other_sessions(Player::PlayerKey key);52 void pause_other_sessions(Player::PlayerKey key);
5453
55private:54private:
5655
=== modified file 'src/core/media/service_skeleton.cpp'
--- src/core/media/service_skeleton.cpp 2016-04-06 15:28:29 +0000
+++ src/core/media/service_skeleton.cpp 2016-05-04 13:11:44 +0000
@@ -63,7 +63,7 @@
63 object(impl->access_service()->add_object_for_path(63 object(impl->access_service()->add_object_for_path(
64 dbus::traits::Service<media::Service>::object_path())),64 dbus::traits::Service<media::Service>::object_path())),
65 configuration(config),65 configuration(config),
66 exported(impl->access_bus(), config.cover_art_resolver, impl)66 exported(impl->access_bus(), config.cover_art_resolver, impl, configuration)
67 {67 {
68 object->install_method_handler<mpris::Service::CreateSession>(68 object->install_method_handler<mpris::Service::CreateSession>(
69 std::bind(69 std::bind(
@@ -95,11 +95,6 @@
95 &Private::handle_resume_session,95 &Private::handle_resume_session,
96 this,96 this,
97 std::placeholders::_1));97 std::placeholders::_1));
98 object->install_method_handler<mpris::Service::SetCurrentPlayer>(
99 std::bind(
100 &Private::handle_set_current_player,
101 this,
102 std::placeholders::_1));
103 object->install_method_handler<mpris::Service::PauseOtherSessions>(98 object->install_method_handler<mpris::Service::PauseOtherSessions>(
104 std::bind(99 std::bind(
105 &Private::handle_pause_other_sessions,100 &Private::handle_pause_other_sessions,
@@ -133,7 +128,8 @@
133 key,128 key,
134 impl->access_bus(),129 impl->access_bus(),
135 impl->access_service(),130 impl->access_service(),
136 impl->access_service()->add_object_for_path(op)131 impl->access_service()->add_object_for_path(op),
132 impl
137 };133 };
138134
139 MH_DEBUG("Session created by request of: %s, key: %d, uuid: %d, path: %s",135 MH_DEBUG("Session created by request of: %s, key: %d, uuid: %d, path: %s",
@@ -241,12 +237,6 @@
241 // Signal player reconnection237 // Signal player reconnection
242 auto player = configuration.player_store->player_for_key(key);238 auto player = configuration.player_store->player_for_key(key);
243 player->reconnect();239 player->reconnect();
244 // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video)
245 if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia)
246 {
247 MH_TRACE("Setting current_player");
248 exported.set_current_player(player);
249 }
250240
251 auto reply = dbus::Message::make_method_return(msg);241 auto reply = dbus::Message::make_method_return(msg);
252 reply->writer() << op;242 reply->writer() << op;
@@ -369,7 +359,8 @@
369 key,359 key,
370 impl->access_bus(),360 impl->access_bus(),
371 impl->access_service(),361 impl->access_service(),
372 impl->access_service()->add_object_for_path(op)362 impl->access_service()->add_object_for_path(op),
363 impl
373 };364 };
374365
375 auto session = impl->create_session(config);366 auto session = impl->create_session(config);
@@ -543,7 +534,7 @@
543 }534 }
544535
545 explicit Exported(const dbus::Bus::Ptr& bus, const media::CoverArtResolver& cover_art_resolver,536 explicit Exported(const dbus::Bus::Ptr& bus, const media::CoverArtResolver& cover_art_resolver,
546 media::ServiceSkeleton* impl)537 media::ServiceSkeleton* impl, const ServiceSkeleton::Configuration& config)
547 : bus{bus},538 : bus{bus},
548 /* Export MediaHub service interface on dbus */539 /* Export MediaHub service interface on dbus */
549 service{dbus::Service::add_service(bus, "org.mpris.MediaPlayer2.MediaHub")},540 service{dbus::Service::add_service(bus, "org.mpris.MediaPlayer2.MediaHub")},
@@ -552,7 +543,8 @@
552 player{mpris::Player::Skeleton::Configuration{bus, object, player_defaults()}},543 player{mpris::Player::Skeleton::Configuration{bus, object, player_defaults()}},
553 playlists{mpris::Playlists::Skeleton::Configuration{bus, object, mpris::Playlists::Skeleton::Configuration::Defaults{}}},544 playlists{mpris::Playlists::Skeleton::Configuration{bus, object, mpris::Playlists::Skeleton::Configuration::Defaults{}}},
554 cover_art_resolver{cover_art_resolver},545 cover_art_resolver{cover_art_resolver},
555 impl{impl}546 impl{impl},
547 service_skel_config(config)
556 {548 {
557 object->install_method_handler<core::dbus::interfaces::Properties::GetAll>([this](const core::dbus::Message::Ptr& msg)549 object->install_method_handler<core::dbus::interfaces::Properties::GetAll>([this](const core::dbus::Message::Ptr& msg)
558 {550 {
@@ -574,7 +566,7 @@
574 // Setup method handlers for mpris::Player methods.566 // Setup method handlers for mpris::Player methods.
575 auto next = [this](const core::dbus::Message::Ptr& msg)567 auto next = [this](const core::dbus::Message::Ptr& msg)
576 {568 {
577 const auto sp = current_player.lock();569 const auto sp = service_skel_config.player_store->current_player().get();
578570
579 if (is_multimedia_role())571 if (is_multimedia_role())
580 sp->next();572 sp->next();
@@ -585,7 +577,7 @@
585577
586 auto previous = [this](const core::dbus::Message::Ptr& msg)578 auto previous = [this](const core::dbus::Message::Ptr& msg)
587 {579 {
588 const auto sp = current_player.lock();580 const auto sp = service_skel_config.player_store->current_player().get();
589581
590 if (is_multimedia_role())582 if (is_multimedia_role())
591 sp->previous();583 sp->previous();
@@ -596,7 +588,7 @@
596588
597 auto pause = [this](const core::dbus::Message::Ptr& msg)589 auto pause = [this](const core::dbus::Message::Ptr& msg)
598 {590 {
599 const auto sp = current_player.lock();591 const auto sp = service_skel_config.player_store->current_player().get();
600592
601 if (is_multimedia_role() and sp->can_pause())593 if (is_multimedia_role() and sp->can_pause())
602 sp->pause();594 sp->pause();
@@ -607,7 +599,7 @@
607599
608 auto stop = [this](const core::dbus::Message::Ptr& msg)600 auto stop = [this](const core::dbus::Message::Ptr& msg)
609 {601 {
610 const auto sp = current_player.lock();602 const auto sp = service_skel_config.player_store->current_player().get();
611603
612 if (is_multimedia_role())604 if (is_multimedia_role())
613 sp->stop();605 sp->stop();
@@ -618,7 +610,7 @@
618610
619 auto play = [this, impl](const core::dbus::Message::Ptr& msg)611 auto play = [this, impl](const core::dbus::Message::Ptr& msg)
620 {612 {
621 const auto sp = current_player.lock();613 const auto sp = service_skel_config.player_store->current_player().get();
622614
623 if (is_multimedia_role() and sp->can_play())615 if (is_multimedia_role() and sp->can_play())
624 {616 {
@@ -636,7 +628,7 @@
636628
637 auto play_pause = [this, impl](const core::dbus::Message::Ptr& msg)629 auto play_pause = [this, impl](const core::dbus::Message::Ptr& msg)
638 {630 {
639 const auto sp = current_player.lock();631 const auto sp = service_skel_config.player_store->current_player().get();
640632
641 if (is_multimedia_role())633 if (is_multimedia_role())
642 {634 {
@@ -662,67 +654,79 @@
662654
663 inline bool is_multimedia_role()655 inline bool is_multimedia_role()
664 {656 {
665 const auto sp = current_player.lock();657 MH_TRACE("");
666658
659 const auto sp = service_skel_config.player_store->current_player().get();
667 return (sp ? sp->audio_stream_role() == media::Player::AudioStreamRole::multimedia : false);660 return (sp ? sp->audio_stream_role() == media::Player::AudioStreamRole::multimedia : false);
668 }661 }
669662
670 void set_current_player(const std::shared_ptr<media::Player>& cp)663 void set_current_player(media::Player::PlayerKey key)
671 {664 {
672 MH_TRACE("");665 MH_TRACE("");
673 // We will not keep the object alive.666
674 current_player = cp;667 // Update the current player in the Player store
668 service_skel_config.player_store->set_current_player_for_key(key);
669 const auto player_sp = service_skel_config.player_store->current_player().get();
675670
676 // And announce that we can be controlled again.671 // And announce that we can be controlled again.
677 player.properties.can_control->set(true);672 player.properties.can_control->set(true);
678673
679 // We wire up player state changes674 // We wire up player state changes
680 connections.seeked_to = cp->seeked_to().connect([this](std::uint64_t position)675 connections.seeked_to = player_sp->seeked_to().connect([this](std::uint64_t position)
681 {676 {
682 player.signals.seeked_to->emit(position);677 player.signals.seeked_to->emit(position);
683 });678 });
684679
685 connections.duration_changed = cp->duration().changed().connect([this](std::uint64_t duration)680 connections.duration_changed = player_sp->duration().changed().connect([this](std::uint64_t duration)
686 {681 {
687 player.properties.duration->set(duration);682 player.properties.duration->set(duration);
688 });683 });
689684
690 connections.position_changed = cp->position().changed().connect([this](std::uint64_t position)685 connections.position_changed = player_sp->position().changed().connect([this](std::uint64_t position)
691 {686 {
692 player.properties.position->set(position);687 player.properties.position->set(position);
693 });688 });
694689
695 connections.playback_status_changed = cp->playback_status().changed().connect(690 connections.playback_status_changed = player_sp->playback_status().changed().connect(
696 [this](core::ubuntu::media::Player::PlaybackStatus status)691 [this, key, player_sp](core::ubuntu::media::Player::PlaybackStatus status)
697 {692 {
698 player.properties.playback_status->set(mpris::Player::PlaybackStatus::from(status));693 const auto cp = service_skel_config.player_store->current_player().get();
694 // If key points to the current player's key, then update status
695 if (cp and key == cp->key())
696 player.properties.playback_status->set(mpris::Player::PlaybackStatus::from(status));
699 });697 });
700698
701 connections.loop_status_changed = cp->loop_status().changed().connect(699 connections.loop_status_changed = player_sp->loop_status().changed().connect(
702 [this](core::ubuntu::media::Player::LoopStatus status)700 [this](core::ubuntu::media::Player::LoopStatus status)
703 {701 {
704 player.properties.loop_status->set(mpris::Player::LoopStatus::from(status));702 player.properties.loop_status->set(mpris::Player::LoopStatus::from(status));
705 });703 });
706704
707 connections.can_play_changed = cp->can_play().changed().connect(705 connections.can_play_changed = player_sp->can_play().changed().connect(
708 [this](bool can_play)706 [this, key, player_sp](bool can_play)
709 {707 {
710 player.properties.can_play->set(can_play);708 const auto cp = service_skel_config.player_store->current_player().get();
711 });709 // If key points to the current player's key, then update can_play
712710 if (cp and key == cp->key())
713 connections.can_pause_changed = cp->can_pause().changed().connect(711 player.properties.can_play->set(can_play);
714 [this](bool can_pause)712 });
715 {713
716 player.properties.can_pause->set(can_pause);714 connections.can_pause_changed = player_sp->can_pause().changed().connect(
717 });715 [this, key, player_sp](bool can_pause)
718716 {
719 connections.can_go_previous_changed = cp->can_go_previous().changed().connect(717 const auto cp = service_skel_config.player_store->current_player().get();
718 // If key points to the current player's key, then update can_pause
719 if (cp and key == cp->key())
720 player.properties.can_pause->set(can_pause);
721 });
722
723 connections.can_go_previous_changed = player_sp->can_go_previous().changed().connect(
720 [this](bool can_go_previous)724 [this](bool can_go_previous)
721 {725 {
722 player.properties.can_go_previous->set(can_go_previous);726 player.properties.can_go_previous->set(can_go_previous);
723 });727 });
724728
725 connections.can_go_next_changed = cp->can_go_next().changed().connect(729 connections.can_go_next_changed = player_sp->can_go_next().changed().connect(
726 [this](bool can_go_next)730 [this](bool can_go_next)
727 {731 {
728 player.properties.can_go_next->set(can_go_next);732 player.properties.can_go_next->set(can_go_next);
@@ -734,16 +738,16 @@
734 // different DBus object paths, /core/ubuntu/media/Service/sessions/<n>738 // different DBus object paths, /core/ubuntu/media/Service/sessions/<n>
735 // and /org/mpris/MediaPlayer2 (this is the one enforced by the MPRIS spec).739 // and /org/mpris/MediaPlayer2 (this is the one enforced by the MPRIS spec).
736 // Discuss why this is needed with tvoss.740 // Discuss why this is needed with tvoss.
737 player.properties.duration->set(cp->duration().get());741 player.properties.duration->set(player_sp->duration().get());
738 player.properties.position->set(cp->position().get());742 player.properties.position->set(player_sp->position().get());
739 player.properties.playback_status->set(mpris::Player::PlaybackStatus::from(743 player.properties.playback_status->set(mpris::Player::PlaybackStatus::from(
740 cp->playback_status().get()));744 player_sp->playback_status().get()));
741 player.properties.loop_status->set(mpris::Player::LoopStatus::from(745 player.properties.loop_status->set(mpris::Player::LoopStatus::from(
742 cp->loop_status().get()));746 player_sp->loop_status().get()));
743 player.properties.can_play->set(cp->can_play().get());747 player.properties.can_play->set(player_sp->can_play().get());
744 player.properties.can_pause->set(cp->can_pause().get());748 player.properties.can_pause->set(player_sp->can_pause().get());
745 player.properties.can_go_previous->set(cp->can_go_previous().get());749 player.properties.can_go_previous->set(player_sp->can_go_previous().get());
746 player.properties.can_go_next->set(cp->can_go_next().get());750 player.properties.can_go_next->set(player_sp->can_go_next().get());
747751
748#if 0752#if 0
749 // TODO cover_art_resolver() is not implemented yet753 // TODO cover_art_resolver() is not implemented yet
@@ -788,7 +792,27 @@
788 MH_TRACE("");792 MH_TRACE("");
789 // And announce that we can no longer be controlled.793 // And announce that we can no longer be controlled.
790 player.properties.can_control->set(false);794 player.properties.can_control->set(false);
791 current_player.reset();795 player.properties.can_play->set(false);
796 player.properties.can_pause->set(false);
797 player.properties.can_go_previous->set(false);
798 player.properties.can_go_next->set(false);
799
800 // Reset to null event connections
801 connections.seeked_to = the_empty_signal.connect([](){});
802 connections.duration_changed = the_empty_signal.connect([](){});
803 connections.position_changed = the_empty_signal.connect([](){});
804 connections.playback_status_changed = the_empty_signal.connect([](){});
805 connections.loop_status_changed = the_empty_signal.connect([](){});
806 connections.can_play_changed = the_empty_signal.connect([](){});
807 connections.can_pause_changed = the_empty_signal.connect([](){});
808 connections.can_go_previous_changed = the_empty_signal.connect([](){});
809 connections.can_go_next_changed = the_empty_signal.connect([](){});
810 }
811
812 bool is_current_player(media::Player::PlayerKey key)
813
814 {
815 return key == service_skel_config.player_store->current_player().get()->key();
792 }816 }
793817
794 dbus::Bus::Ptr bus;818 dbus::Bus::Ptr bus;
@@ -801,10 +825,9 @@
801825
802 // The CoverArtResolver used by the exported player.826 // The CoverArtResolver used by the exported player.
803 media::CoverArtResolver cover_art_resolver;827 media::CoverArtResolver cover_art_resolver;
804 // The actual player instance.
805 std::weak_ptr<media::Player> current_player;
806828
807 media::ServiceSkeleton* impl;829 media::ServiceSkeleton* impl;
830 ServiceSkeleton::Configuration service_skel_config;
808831
809 // We track event connections.832 // We track event connections.
810 struct833 struct
@@ -899,11 +922,23 @@
899 d->configuration.player_store->player_for_key(key);922 d->configuration.player_store->player_for_key(key);
900 // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video)923 // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video)
901 if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia)924 if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia)
902 d->exported.set_current_player(player);925 d->exported.set_current_player(key);
926}
927
928bool media::ServiceSkeleton::is_current_player(media::Player::PlayerKey key) const
929{
930 return d->exported.is_current_player(key);
931}
932
933void media::ServiceSkeleton::reset_current_player()
934{
935 MH_TRACE("");
936 d->exported.reset_current_player();
903}937}
904938
905void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key)939void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key)
906{940{
941 MH_TRACE("");
907 d->configuration.impl->pause_other_sessions(key);942 d->configuration.impl->pause_other_sessions(key);
908}943}
909944
910945
=== modified file 'src/core/media/service_skeleton.h'
--- src/core/media/service_skeleton.h 2015-09-08 20:03:56 +0000
+++ src/core/media/service_skeleton.h 2016-05-04 13:11:44 +0000
@@ -60,6 +60,8 @@
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&);
61 std::shared_ptr<Player> resume_session(Player::PlayerKey);61 std::shared_ptr<Player> resume_session(Player::PlayerKey);
62 void set_current_player(Player::PlayerKey key);62 void set_current_player(Player::PlayerKey key);
63 bool is_current_player(Player::PlayerKey key) const;
64 void reset_current_player();
63 void pause_other_sessions(Player::PlayerKey key);65 void pause_other_sessions(Player::PlayerKey key);
6466
65 void run();67 void run();
6668
=== modified file 'src/core/media/service_stub.cpp'
--- src/core/media/service_stub.cpp 2015-09-08 20:03:56 +0000
+++ src/core/media/service_stub.cpp 2016-05-04 13:11:44 +0000
@@ -139,15 +139,6 @@
139 });139 });
140}140}
141141
142void media::ServiceStub::set_current_player(Player::PlayerKey key)
143{
144 auto op = d->object->invoke_method_synchronously<mpris::Service::SetCurrentPlayer,
145 void>(key);
146
147 if (op.is_error())
148 throw std::runtime_error("Problem setting current player: " + op.error());
149}
150
151void media::ServiceStub::pause_other_sessions(media::Player::PlayerKey key)142void media::ServiceStub::pause_other_sessions(media::Player::PlayerKey key)
152{143{
153 auto op = d->object->invoke_method_synchronously<mpris::Service::PauseOtherSessions,144 auto op = d->object->invoke_method_synchronously<mpris::Service::PauseOtherSessions,
154145
=== modified file 'src/core/media/service_stub.h'
--- src/core/media/service_stub.h 2015-09-08 20:03:56 +0000
+++ src/core/media/service_stub.h 2016-05-04 13:11:44 +0000
@@ -45,7 +45,6 @@
45 void destroy_session(const std::string& uuid, const Player::Configuration&);45 void destroy_session(const std::string& uuid, const Player::Configuration&);
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&);
47 std::shared_ptr<Player> resume_session(Player::PlayerKey key);47 std::shared_ptr<Player> resume_session(Player::PlayerKey key);
48 void set_current_player(Player::PlayerKey key);
49 void pause_other_sessions(Player::PlayerKey key);48 void pause_other_sessions(Player::PlayerKey key);
5049
51 private:50 private:

Subscribers

People subscribed via source and target branches

to all changes: