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

Proposed by Konrad Zapałowicz
Status: Approved
Approved by: Alfonso Sanchez-Beato
Approved revision: 185
Proposed branch: lp:~phablet-team/media-hub/fix-1538703
Merge into: lp:media-hub
Diff against target: 322 lines (+125/-17)
9 files modified
debian/libmedia-hub-doc.install (+1/-1)
doc/CMakeLists.txt (+2/-2)
include/core/media/service.h (+0/-3)
src/core/media/player_configuration.h (+3/-0)
src/core/media/player_implementation.cpp (+68/-6)
src/core/media/player_skeleton.h (+2/-0)
src/core/media/service_implementation.cpp (+3/-3)
src/core/media/service_skeleton.cpp (+35/-2)
src/core/media/service_skeleton.h (+11/-0)
To merge this branch: bzr merge lp:~phablet-team/media-hub/fix-1538703
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
Review via email: mp+292038@code.launchpad.net

This proposal supersedes a proposal from 2016-04-12.

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
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : Posted in a previous version of this proposal

Looks good, but maybe we need to call update_current_player() also when adding complete track lists? Which is done with AddTrack(s) DBus calls.

review: Needs Information
Revision history for this message
Jim Hodapp (jhodapp) wrote : Posted in a previous version of this proposal

> Looks good, but maybe we need to call update_current_player() also when adding
> complete track lists? Which is done with AddTrack(s) DBus calls.

Can you explain more why you think we need to do this? I don't see any gap that this would fix.

Revision history for this message
Jim Hodapp (jhodapp) wrote : Posted in a previous version of this proposal

Addressed review comments.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : Posted in a previous version of this proposal

LGTM

review: Approve
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : Posted in a previous version of this proposal

So I have just seen that Jim modified service.h too to add reset_current_player(), for some reason I did not notice last time I reviewed. TBH I do not like adding reset_current_player() and get_current_player() to service.h. That file is, in the end, defining a DBus interface so we should add only functions that make sense to a media-hub client, and these functions are not even implemented in the service stub (client library).

I think that changing PlayerSkeleton so player_service is a pointer to ServiceSkeleton, and implementing these functions only in ServiceSkeleton should work. We will make sure the DBus interface is not contaminated and we remove the need for dummy implementations in ServiceStub and ServiceImplementation.

@Konrad maybe we con wait for Jim if you do not feel comfortable with this change.

Finally, I appreciate the long description in the last commit message, but I think most of it should move to a comment inside the code so it is more easily found.

The change looks good beside this issue with service.h.

review: Needs Fixing
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote : Posted in a previous version of this proposal

Thanks for the review and I will try to make the changes that you suggest. Either I'm successful or not and the Jim will take over when he is back however before that happens I will get my hands dirty :)

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

LGTM

review: Approve
186. By Jim Hodapp

Pass a Service* instead of ServiceSkeleton* to avoid weird inheritance segfault

Unmerged revisions

186. By Jim Hodapp

Pass a Service* instead of ServiceSkeleton* to avoid weird inheritance segfault

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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-04-20 15:59:04 +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-04-20 15:59:04 +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-04-20 15:59:04 +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/player_configuration.h'
--- src/core/media/player_configuration.h 2015-04-17 16:44:30 +0000
+++ src/core/media/player_configuration.h 2016-04-20 15:59:04 +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-02-19 16:14:42 +0000
+++ src/core/media/player_implementation.cpp 2016-04-20 15:59:04 +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>
@@ -302,14 +305,14 @@
302 }305 }
303 }306 }
304307
305 void update_mpris_properties(void)308 void update_mpris_properties()
306 {309 {
307 bool has_previous = track_list->has_previous()310 const bool has_previous = track_list->has_previous()
308 or parent->Parent::loop_status() != Player::LoopStatus::none;311 or parent->Parent::loop_status() != Player::LoopStatus::none;
309 bool has_next = track_list->has_next()312 const bool has_next = track_list->has_next()
310 or parent->Parent::loop_status() != Player::LoopStatus::none;313 or parent->Parent::loop_status() != Player::LoopStatus::none;
311 auto n_tracks = track_list->tracks()->size();314 const auto n_tracks = track_list->tracks()->size();
312 bool has_tracks = (n_tracks > 0) ? true : false;315 const bool has_tracks = (n_tracks > 0) ? true : false;
313316
314 std::cout << "Updating MPRIS TrackList properties"317 std::cout << "Updating MPRIS TrackList properties"
315 << "; Tracks: " << n_tracks318 << "; Tracks: " << n_tracks
@@ -323,6 +326,40 @@
323 parent->can_go_next().set(has_next);326 parent->can_go_next().set(has_next);
324 }327 }
325328
329 ServiceSkeleton* get_player_service_skeleton() const
330 {
331 return reinterpret_cast<ServiceSkeleton*>(config.parent.player_service);
332 }
333
334 bool update_current_player(const media::Player::PlayerKey& key)
335 {
336 if (not config.parent.player_service)
337 return false;
338
339 get_player_service_skeleton()->set_current_player(key);
340 return true;
341 }
342
343 // Utility to hide the complexity of getting the ptr to current player
344 bool is_current_player(const media::PlayerImplementation<Parent> *p) const
345 {
346 return p == get_player_service_skeleton()->get_current_player().get();
347 }
348
349 bool is_multimedia_role() const
350 {
351 return get_player_service_skeleton()->is_multimedia_role();
352 }
353
354 bool reset_current_player()
355 {
356 if (not get_player_service_skeleton())
357 return false;
358
359 get_player_service_skeleton()->reset_current_player();
360 return true;
361 }
362
326 // Our link back to our parent.363 // Our link back to our parent.
327 media::PlayerImplementation<Parent>* parent;364 media::PlayerImplementation<Parent>* parent;
328 // We just store the parameters passed on construction.365 // We just store the parameters passed on construction.
@@ -479,6 +516,20 @@
479 // are cleared516 // are cleared
480 d->clear_wakelocks();517 d->clear_wakelocks();
481 d->track_list->reset();518 d->track_list->reset();
519
520 // Here it is decided if it is good to reset the current player. The
521 // conditions to do so are very simple. It must be a multimedia role
522 // and the Player that disconnected must be the last player to play
523 // audio/video.
524 if (d->is_multimedia_role() && d->is_current_player(this))
525 {
526 // This is not a fatal error but merely
527 // a warning that should be logged
528 if (not d->reset_current_player())
529 std::cerr << "Failed to reset current player in "
530 << __PRETTY_FUNCTION__ << std::endl;
531 }
532
482 // And tell the outside world that the client has gone away533 // And tell the outside world that the client has gone away
483 d->on_client_disconnected();534 d->on_client_disconnected();
484 });535 });
@@ -688,7 +739,8 @@
688 d->track_list->reset();739 d->track_list->reset();
689740
690 // If empty uri, give the same meaning as QMediaPlayer::setMedia("")741 // If empty uri, give the same meaning as QMediaPlayer::setMedia("")
691 if (uri.empty()) {742 if (uri.empty())
743 {
692 cout << __PRETTY_FUNCTION__ << ": resetting current media" << endl;744 cout << __PRETTY_FUNCTION__ << ": resetting current media" << endl;
693 return true;745 return true;
694 }746 }
@@ -698,6 +750,7 @@
698 // Don't set new track as the current track to play since we're calling open_resource_for_uri above750 // Don't set new track as the current track to play since we're calling open_resource_for_uri above
699 static const bool make_current = false;751 static const bool make_current = false;
700 d->track_list->add_track_with_uri_at(uri, media::TrackList::after_empty_track(), make_current);752 d->track_list->add_track_with_uri_at(uri, media::TrackList::after_empty_track(), make_current);
753
701 return ret;754 return ret;
702}755}
703756
@@ -722,6 +775,15 @@
722template<typename Parent>775template<typename Parent>
723void media::PlayerImplementation<Parent>::play()776void media::PlayerImplementation<Parent>::play()
724{777{
778 if (Parent::audio_stream_role() == media::Player::AudioStreamRole::multimedia)
779 {
780 std::cout << "==== Updating the current player from " << __PRETTY_FUNCTION__ << std::endl;
781 // This player will begin playing so make sure it's the current player. If
782 // this operation fails it is not a fatal condition but should be logged
783 if (not d->update_current_player(d->config.key))
784 std::cerr << "Failed to update current player in " << __PRETTY_FUNCTION__ << std::endl;
785 }
786
725 d->engine->play();787 d->engine->play();
726}788}
727789
728790
=== 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-04-20 15:59:04 +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-03-02 18:32:46 +0000
+++ src/core/media/service_implementation.cpp 2016-04-20 15:59:04 +0000
@@ -185,11 +185,13 @@
185 auto player = std::make_shared<media::PlayerImplementation<media::PlayerSkeleton>>185 auto player = std::make_shared<media::PlayerImplementation<media::PlayerSkeleton>>
186 (media::PlayerImplementation<media::PlayerSkeleton>::Configuration186 (media::PlayerImplementation<media::PlayerSkeleton>::Configuration
187 {187 {
188 // Derive a PlayerSkeleton-specific Configuration based on Player::Configuration
188 media::PlayerSkeleton::Configuration189 media::PlayerSkeleton::Configuration
189 {190 {
190 conf.bus,191 conf.bus,
191 conf.service,192 conf.service,
192 conf.session,193 conf.session,
194 conf.player_service,
193 d->request_context_resolver,195 d->request_context_resolver,
194 d->request_authenticator196 d->request_authenticator
195 },197 },
@@ -259,13 +261,11 @@
259261
260void media::ServiceImplementation::set_current_player(Player::PlayerKey)262void media::ServiceImplementation::set_current_player(Player::PlayerKey)
261{263{
262 // no impl264 // no impl
263}265}
264266
265void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)267void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)
266{268{
267 std::cout << __PRETTY_FUNCTION__ << std::endl;
268
269 if (not d->configuration.player_store->has_player_for_key(key))269 if (not d->configuration.player_store->has_player_for_key(key))
270 {270 {
271 cerr << "Could not find Player by key: " << key << endl;271 cerr << "Could not find Player by key: " << key << endl;
272272
=== modified file 'src/core/media/service_skeleton.cpp'
--- src/core/media/service_skeleton.cpp 2016-03-02 18:32:46 +0000
+++ src/core/media/service_skeleton.cpp 2016-04-20 15:59:04 +0000
@@ -131,7 +131,8 @@
131 key,131 key,
132 impl->access_bus(),132 impl->access_bus(),
133 impl->access_service(),133 impl->access_service(),
134 impl->access_service()->add_object_for_path(op)134 impl->access_service()->add_object_for_path(op),
135 impl
135 };136 };
136137
137 cout << "Session created by request of: " << msg->sender()138 cout << "Session created by request of: " << msg->sender()
@@ -366,7 +367,8 @@
366 key,367 key,
367 impl->access_bus(),368 impl->access_bus(),
368 impl->access_service(),369 impl->access_service(),
369 impl->access_service()->add_object_for_path(op)370 impl->access_service()->add_object_for_path(op),
371 impl
370 };372 };
371373
372 auto session = impl->create_session(config);374 auto session = impl->create_session(config);
@@ -787,6 +789,22 @@
787 std::cout << __PRETTY_FUNCTION__ << std::endl;789 std::cout << __PRETTY_FUNCTION__ << std::endl;
788 // And announce that we can no longer be controlled.790 // And announce that we can no longer be controlled.
789 player.properties.can_control->set(false);791 player.properties.can_control->set(false);
792 player.properties.can_play->set(false);
793 player.properties.can_pause->set(false);
794 player.properties.can_go_previous->set(false);
795 player.properties.can_go_next->set(false);
796
797 // Reset to null event connections
798 connections.seeked_to = the_empty_signal.connect([](){});
799 connections.duration_changed = the_empty_signal.connect([](){});
800 connections.position_changed = the_empty_signal.connect([](){});
801 connections.playback_status_changed = the_empty_signal.connect([](){});
802 connections.loop_status_changed = the_empty_signal.connect([](){});
803 connections.can_play_changed = the_empty_signal.connect([](){});
804 connections.can_pause_changed = the_empty_signal.connect([](){});
805 connections.can_go_previous_changed = the_empty_signal.connect([](){});
806 connections.can_go_next_changed = the_empty_signal.connect([](){});
807
790 current_player.reset();808 current_player.reset();
791 }809 }
792810
@@ -901,6 +919,21 @@
901 d->exported.set_current_player(player);919 d->exported.set_current_player(player);
902}920}
903921
922bool media::ServiceSkeleton::is_multimedia_role() const
923{
924 return d->exported.is_multimedia_role();
925}
926
927std::shared_ptr<media::Player> media::ServiceSkeleton::get_current_player() const
928{
929 return d->exported.current_player.lock();
930}
931
932void media::ServiceSkeleton::reset_current_player()
933{
934 d->exported.reset_current_player();
935}
936
904void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key)937void media::ServiceSkeleton::pause_other_sessions(media::Player::PlayerKey key)
905{938{
906 d->configuration.impl->pause_other_sessions(key);939 d->configuration.impl->pause_other_sessions(key);
907940
=== 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-04-20 15:59:04 +0000
@@ -60,6 +60,17 @@
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
64 /** @brief returns true for multimedia role */
65 bool is_multimedia_role() const;
66
67 /** @brief gets the current player controlled by MRIS */
68 std::shared_ptr<Player> get_current_player() const;
69
70 /** @detail Resets the current player so that the MPRIS interface will no
71 * longer have a current player to control
72 */
73 void reset_current_player();
63 void pause_other_sessions(Player::PlayerKey key);74 void pause_other_sessions(Player::PlayerKey key);
6475
65 void run();76 void run();

Subscribers

People subscribed via source and target branches

to all changes: