Merge lp:~ricmm/media-hub/session-reattach-nonfixed into lp:media-hub
- session-reattach-nonfixed
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Jim Hodapp |
Approved revision: | 155 |
Merged at revision: | 133 |
Proposed branch: | lp:~ricmm/media-hub/session-reattach-nonfixed |
Merge into: | lp:media-hub |
Prerequisite: | lp:~phablet-team/media-hub/tracklist-cli |
Diff against target: |
1135 lines (+555/-61) 19 files modified
CMakeLists.txt (+1/-1) debian/changelog (+6/-0) include/core/media/player.h (+4/-0) include/core/media/service.h (+16/-0) src/core/media/mpris/service.h (+39/-0) src/core/media/player_configuration.h (+1/-1) src/core/media/player_implementation.cpp (+47/-17) src/core/media/player_implementation.h (+4/-0) src/core/media/player_stub.cpp (+22/-3) src/core/media/player_stub.h (+6/-1) src/core/media/server/server.cpp (+1/-1) src/core/media/service_implementation.cpp (+16/-0) src/core/media/service_implementation.h (+3/-0) src/core/media/service_skeleton.cpp (+235/-12) src/core/media/service_skeleton.h (+6/-0) src/core/media/service_stub.cpp (+39/-3) src/core/media/service_stub.h (+3/-0) tests/test-track-list/test_track_list.cpp (+99/-20) tests/test-track-list/test_track_list.h (+7/-2) |
To merge this branch: | bzr merge lp:~ricmm/media-hub/session-reattach-nonfixed |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Thomas Voß (community) | Approve | ||
Jim Hodapp (community) | code | Approve | |
Review via email:
|
This proposal supersedes a proposal from 2015-04-10.
Commit message
Player session attaching/detaching with UUID
Description of the change
Player session attaching/detaching with UUID
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jim Hodapp (jhodapp) wrote : | # |
Looks good, a few things to fix.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:139
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jim Hodapp (jhodapp) wrote : | # |
Looks good, thanks.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:140
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 141. By Ricardo Mendoza
-
Merge parent
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:141
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Thomas Voß (thomas-voss) wrote : | # |
A few comments inline, one bigger question:
What is the difference between reattach/detach and the existing resume_session functionality?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jim Hodapp (jhodapp) wrote : | # |
Some added comments to my review and tvoss' review.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Thomas Voß (thomas-voss) wrote : | # |
Replied inline.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Jim Hodapp (jhodapp) : | # |
- 142. By Ricardo Mendoza
-
Address review comments and plug through no-impl methods of the Service parts
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:142
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 143. By Ricardo Mendoza
-
Not a reference
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:143
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 144. By Ricardo Mendoza
-
Correctly propagate track list changes from bus to local and viceversa
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:144
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Thomas Voß (thomas-voss) wrote : | # |
On Thu, Apr 16, 2015 at 5:14 PM, Jim Hodapp <email address hidden> wrote:
>
>
> Diff comments:
>
>> === modified file 'CMakeLists.txt'
>> --- CMakeLists.txt 2015-01-23 13:00:36 +0000
>> +++ CMakeLists.txt 2015-04-15 18:29:47 +0000
>> @@ -3,7 +3,7 @@
>> project(
>>
>> set(UBUNTU_
>> -set(UBUNTU_
>> +set(UBUNTU_
>> set(UBUNTU_
>>
>> set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fPIC -pthread")
>>
>> === modified file 'debian/changelog'
>> --- debian/changelog 2015-04-02 16:43:42 +0000
>> +++ debian/changelog 2015-04-15 18:29:47 +0000
>> @@ -1,3 +1,9 @@
>> +media-hub (3.1.0) UNRELEASED; urgency=medium
>> +
>> + * Support for signalling player reconnection up the stack.
>> +
>> + -- Ricardo Mendoza <email address hidden> Fri, 10 Apr 2015 18:20:32 +0200
>> +
>> media-hub (3.0.0+
>>
>> [ Jim Hodapp ]
>>
>> === modified file 'include/
>> --- include/
>> +++ include/
>> @@ -126,6 +126,9 @@
>> Player& operator=(const Player&) = delete;
>> bool operator==(const Player&) const = delete;
>>
>> + virtual std::string uuid() const = 0;
>
> Yeah I would say this isn't hugely important though as the likely-hood of this happening is very slim. Also, we could just change it if that unlikely event occurred.
>
That's somewhat difficult as this is public facing API. Your call.
>> + virtual void reconnect() = 0;
>> +
>> virtual std::shared_
>> virtual PlayerKey key() const = 0;
>>
>>
>> === modified file 'include/
>> --- include/
>> +++ include/
>> @@ -42,9 +42,25 @@
>> Service& operator=(const Service&) = delete;
>> bool operator==(const Service&) const = delete;
>>
>> + /** @brief Creates a session with the media-hub service. */
>> virtual std::shared_
>> +
>> + /** @brief Detaches a UUID-identified session for later resuming. */
>> + virtual void detach_
>> +
>> + /** @brief Reattaches to a UUID-identified session that is in detached state. */
>> + virtual std::shared_
>> +
>> + /** @brief Asks the service to destroy a session. The session is destroyed when the client exits. */
>> + virtual void destroy_
>> +
>> + /** @brief Creates a fixed-named session with the media-hub service. */
>> virtual std::shared_
>> +
>> + /** @brief Resumes a fixed-name session directly by player key. */
>> virtual std::shared_
- 145. By Ricardo Mendoza
-
Remove printfs
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:145
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 146. By Ricardo Mendoza
-
Revert last changes
- 147. By Ricardo Mendoza
-
Delete player instance instead of abandoning
- 148. By Ricardo Mendoza
-
Update tracklist cli for new api
- 149. By Ricardo Mendoza
-
Merge parent
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:149
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 150. By Ricardo Mendoza
-
Implement full player destruction
- 151. By Ricardo Mendoza
-
Merge parent
- 152. By Ricardo Mendoza
-
Syntax error
- 153. By Ricardo Mendoza
-
Sync test cli
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:152
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:153
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 154. By Ricardo Mendoza
-
Merge parent
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:154
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 155. By Ricardo Mendoza
-
Merge parent
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:155
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-01-23 13:00:36 +0000 | |||
3 | +++ CMakeLists.txt 2015-04-20 15:56:34 +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 0) | 6 | set(UBUNTU_MEDIA_HUB_VERSION_MINOR 1) |
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 'debian/changelog' | |||
15 | --- debian/changelog 2015-04-02 16:43:42 +0000 | |||
16 | +++ debian/changelog 2015-04-20 15:56:34 +0000 | |||
17 | @@ -1,3 +1,9 @@ | |||
18 | 1 | media-hub (3.1.0) UNRELEASED; urgency=medium | ||
19 | 2 | |||
20 | 3 | * Support for signalling player reconnection up the stack. | ||
21 | 4 | |||
22 | 5 | -- Ricardo Mendoza <ricardo.mendoza@canonical.com> Fri, 10 Apr 2015 18:20:32 +0200 | ||
23 | 6 | |||
24 | 1 | media-hub (3.0.0+15.04.20150402-0ubuntu1) vivid; urgency=medium | 7 | media-hub (3.0.0+15.04.20150402-0ubuntu1) vivid; urgency=medium |
25 | 2 | 8 | ||
26 | 3 | [ Jim Hodapp ] | 9 | [ Jim Hodapp ] |
27 | 4 | 10 | ||
28 | === modified file 'include/core/media/player.h' | |||
29 | --- include/core/media/player.h 2015-04-20 15:56:34 +0000 | |||
30 | +++ include/core/media/player.h 2015-04-20 15:56:34 +0000 | |||
31 | @@ -126,6 +126,10 @@ | |||
32 | 126 | Player& operator=(const Player&) = delete; | 126 | Player& operator=(const Player&) = delete; |
33 | 127 | bool operator==(const Player&) const = delete; | 127 | bool operator==(const Player&) const = delete; |
34 | 128 | 128 | ||
35 | 129 | virtual std::string uuid() const = 0; | ||
36 | 130 | virtual void reconnect() = 0; | ||
37 | 131 | virtual void abandon() = 0; | ||
38 | 132 | |||
39 | 129 | virtual std::shared_ptr<TrackList> track_list() = 0; | 133 | virtual std::shared_ptr<TrackList> track_list() = 0; |
40 | 130 | virtual PlayerKey key() const = 0; | 134 | virtual PlayerKey key() const = 0; |
41 | 131 | 135 | ||
42 | 132 | 136 | ||
43 | === modified file 'include/core/media/service.h' | |||
44 | --- include/core/media/service.h 2014-09-30 06:51:15 +0000 | |||
45 | +++ include/core/media/service.h 2015-04-20 15:56:34 +0000 | |||
46 | @@ -42,9 +42,25 @@ | |||
47 | 42 | Service& operator=(const Service&) = delete; | 42 | Service& operator=(const Service&) = delete; |
48 | 43 | bool operator==(const Service&) const = delete; | 43 | bool operator==(const Service&) const = delete; |
49 | 44 | 44 | ||
50 | 45 | /** @brief Creates a session with the media-hub service. */ | ||
51 | 45 | virtual std::shared_ptr<Player> create_session(const Player::Configuration&) = 0; | 46 | virtual std::shared_ptr<Player> create_session(const Player::Configuration&) = 0; |
52 | 47 | |||
53 | 48 | /** @brief Detaches a UUID-identified session for later resuming. */ | ||
54 | 49 | virtual void detach_session(const std::string& uuid, const Player::Configuration&) = 0; | ||
55 | 50 | |||
56 | 51 | /** @brief Reattaches to a UUID-identified session that is in detached state. */ | ||
57 | 52 | virtual std::shared_ptr<Player> reattach_session(const std::string& uuid, const Player::Configuration&) = 0; | ||
58 | 53 | |||
59 | 54 | /** @brief Asks the service to destroy a session. The session is destroyed when the client exits. */ | ||
60 | 55 | virtual void destroy_session(const std::string& uuid, const Player::Configuration&) = 0; | ||
61 | 56 | |||
62 | 57 | /** @brief Creates a fixed-named session with the media-hub service. */ | ||
63 | 46 | virtual std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&) = 0; | 58 | virtual std::shared_ptr<Player> create_fixed_session(const std::string& name, const Player::Configuration&) = 0; |
64 | 59 | |||
65 | 60 | /** @brief Resumes a fixed-name session directly by player key. */ | ||
66 | 47 | virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0; | 61 | virtual std::shared_ptr<Player> resume_session(Player::PlayerKey) = 0; |
67 | 62 | |||
68 | 63 | /** @brief Pauses sessions other than the supplied one. */ | ||
69 | 48 | virtual void pause_other_sessions(Player::PlayerKey) = 0; | 64 | virtual void pause_other_sessions(Player::PlayerKey) = 0; |
70 | 49 | 65 | ||
71 | 50 | protected: | 66 | protected: |
72 | 51 | 67 | ||
73 | === modified file 'src/core/media/mpris/service.h' | |||
74 | --- src/core/media/mpris/service.h 2014-09-30 06:51:15 +0000 | |||
75 | +++ src/core/media/mpris/service.h 2015-04-20 15:56:34 +0000 | |||
76 | @@ -48,6 +48,42 @@ | |||
77 | 48 | } | 48 | } |
78 | 49 | }; | 49 | }; |
79 | 50 | 50 | ||
80 | 51 | struct DetachingSession | ||
81 | 52 | { | ||
82 | 53 | static const std::string& name() | ||
83 | 54 | { | ||
84 | 55 | static const std::string s | ||
85 | 56 | { | ||
86 | 57 | "core.ubuntu.media.Service.Error.DetachingSession" | ||
87 | 58 | }; | ||
88 | 59 | return s; | ||
89 | 60 | } | ||
90 | 61 | }; | ||
91 | 62 | |||
92 | 63 | struct ReattachingSession | ||
93 | 64 | { | ||
94 | 65 | static const std::string& name() | ||
95 | 66 | { | ||
96 | 67 | static const std::string s | ||
97 | 68 | { | ||
98 | 69 | "core.ubuntu.media.Service.Error.ReattachingSession" | ||
99 | 70 | }; | ||
100 | 71 | return s; | ||
101 | 72 | } | ||
102 | 73 | }; | ||
103 | 74 | |||
104 | 75 | struct DestroyingSession | ||
105 | 76 | { | ||
106 | 77 | static const std::string& name() | ||
107 | 78 | { | ||
108 | 79 | static const std::string s | ||
109 | 80 | { | ||
110 | 81 | "core.ubuntu.media.Service.Error.DestroyingSession" | ||
111 | 82 | }; | ||
112 | 83 | return s; | ||
113 | 84 | } | ||
114 | 85 | }; | ||
115 | 86 | |||
116 | 51 | struct CreatingFixedSession | 87 | struct CreatingFixedSession |
117 | 52 | { | 88 | { |
118 | 53 | static const std::string& name() | 89 | static const std::string& name() |
119 | @@ -74,6 +110,9 @@ | |||
120 | 74 | }; | 110 | }; |
121 | 75 | 111 | ||
122 | 76 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateSession, Service, 1000) | 112 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateSession, Service, 1000) |
123 | 113 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DetachSession, Service, 1000) | ||
124 | 114 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ReattachSession, Service, 1000) | ||
125 | 115 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(DestroySession, Service, 1000) | ||
126 | 77 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000) | 116 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateFixedSession, Service, 1000) |
127 | 78 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000) | 117 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(ResumeSession, Service, 1000) |
128 | 79 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000) | 118 | DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(PauseOtherSessions, Service, 1000) |
129 | 80 | 119 | ||
130 | === modified file 'src/core/media/player_configuration.h' | |||
131 | --- src/core/media/player_configuration.h 2015-04-20 15:56:34 +0000 | |||
132 | +++ src/core/media/player_configuration.h 2015-04-20 15:56:34 +0000 | |||
133 | @@ -27,7 +27,7 @@ | |||
134 | 27 | // to the implementation in a way that is opaque to the client. | 27 | // to the implementation in a way that is opaque to the client. |
135 | 28 | struct core::ubuntu::media::Player::Configuration | 28 | struct core::ubuntu::media::Player::Configuration |
136 | 29 | { | 29 | { |
138 | 30 | // Unique key for identifying the session. | 30 | // Unique key for identifying the session path. |
139 | 31 | core::ubuntu::media::Player::PlayerKey key; | 31 | core::ubuntu::media::Player::PlayerKey key; |
140 | 32 | // The bus connection to expose objects on. | 32 | // The bus connection to expose objects on. |
141 | 33 | std::shared_ptr<core::dbus::Bus> bus; | 33 | std::shared_ptr<core::dbus::Bus> bus; |
142 | 34 | 34 | ||
143 | === modified file 'src/core/media/player_implementation.cpp' | |||
144 | --- src/core/media/player_implementation.cpp 2015-04-20 15:56:34 +0000 | |||
145 | +++ src/core/media/player_implementation.cpp 2015-04-20 15:56:34 +0000 | |||
146 | @@ -68,7 +68,7 @@ | |||
147 | 68 | previous_state(Engine::State::stopped), | 68 | previous_state(Engine::State::stopped), |
148 | 69 | engine_state_change_connection(engine->state().changed().connect(make_state_change_handler())), | 69 | engine_state_change_connection(engine->state().changed().connect(make_state_change_handler())), |
149 | 70 | engine_playback_status_change_connection(engine->playback_status_changed_signal().connect(make_playback_status_change_handler())), | 70 | engine_playback_status_change_connection(engine->playback_status_changed_signal().connect(make_playback_status_change_handler())), |
151 | 71 | doing_go_to_track(false) | 71 | doing_abandon(false) |
152 | 72 | { | 72 | { |
153 | 73 | // Poor man's logging of release/acquire events. | 73 | // Poor man's logging of release/acquire events. |
154 | 74 | display_state_lock->acquired().connect([](media::power::DisplayState state) | 74 | display_state_lock->acquired().connect([](media::power::DisplayState state) |
155 | @@ -301,7 +301,8 @@ | |||
156 | 301 | core::Connection engine_state_change_connection; | 301 | core::Connection engine_state_change_connection; |
157 | 302 | core::Connection engine_playback_status_change_connection; | 302 | core::Connection engine_playback_status_change_connection; |
158 | 303 | // Prevent the TrackList from auto advancing to the next track | 303 | // Prevent the TrackList from auto advancing to the next track |
160 | 304 | std::atomic<bool> doing_go_to_track; | 304 | std::mutex doing_go_to_track; |
161 | 305 | std::atomic<bool> doing_abandon; | ||
162 | 305 | }; | 306 | }; |
163 | 306 | 307 | ||
164 | 307 | template<typename Parent> | 308 | template<typename Parent> |
165 | @@ -390,23 +391,26 @@ | |||
166 | 390 | 391 | ||
167 | 391 | d->engine->about_to_finish_signal().connect([this]() | 392 | d->engine->about_to_finish_signal().connect([this]() |
168 | 392 | { | 393 | { |
169 | 394 | if (d->doing_abandon) | ||
170 | 395 | return; | ||
171 | 396 | |||
172 | 393 | Parent::about_to_finish()(); | 397 | Parent::about_to_finish()(); |
173 | 394 | 398 | ||
175 | 395 | if (!d->doing_go_to_track) | 399 | // This lambda needs to be mutually exclusive with the on_go_to_track lambda below |
176 | 400 | d->doing_go_to_track.lock(); | ||
177 | 401 | |||
178 | 402 | const media::Track::Id prev_track_id = d->track_list->current(); | ||
179 | 403 | // Make sure that the TrackList keeps advancing. The logic for what gets played next, | ||
180 | 404 | // if anything at all, occurs in TrackListSkeleton::next() | ||
181 | 405 | const Track::UriType uri = d->track_list->query_uri_for_track(d->track_list->next()); | ||
182 | 406 | if (prev_track_id != d->track_list->current() && !uri.empty()) | ||
183 | 396 | { | 407 | { |
194 | 397 | const media::Track::Id prev_track_id = d->track_list->current(); | 408 | std::cout << "Setting next track on playbin: " << uri << std::endl; |
195 | 398 | // Make sure that the TrackList keeps advancing. The logic for what gets played next, | 409 | static const bool do_pipeline_reset = false; |
196 | 399 | // if anything at all, occurs in TrackListSkeleton::next() | 410 | d->engine->open_resource_for_uri(uri, do_pipeline_reset); |
187 | 400 | const Track::UriType uri = d->track_list->query_uri_for_track(d->track_list->next()); | ||
188 | 401 | if (prev_track_id != d->track_list->current() && !uri.empty()) | ||
189 | 402 | { | ||
190 | 403 | std::cout << "Setting next track on playbin: " << uri << std::endl; | ||
191 | 404 | static const bool do_pipeline_reset = false; | ||
192 | 405 | d->engine->open_resource_for_uri(uri, do_pipeline_reset); | ||
193 | 406 | } | ||
197 | 407 | } | 411 | } |
200 | 408 | else | 412 | |
201 | 409 | std::cout << "Not auto-advancing the TrackList since doing_go_to_track is true" << std::endl; | 413 | d->doing_go_to_track.unlock(); |
202 | 410 | }); | 414 | }); |
203 | 411 | 415 | ||
204 | 412 | d->engine->client_disconnected_signal().connect([this]() | 416 | d->engine->client_disconnected_signal().connect([this]() |
205 | @@ -443,7 +447,8 @@ | |||
206 | 443 | { | 447 | { |
207 | 444 | // This prevents the TrackList from auto advancing in other areas such as the about_to_finish signal | 448 | // This prevents the TrackList from auto advancing in other areas such as the about_to_finish signal |
208 | 445 | // handler. | 449 | // handler. |
210 | 446 | d->doing_go_to_track = true; | 450 | // This lambda needs to be mutually exclusive with the about_to_finish lambda above |
211 | 451 | d->doing_go_to_track.lock(); | ||
212 | 447 | 452 | ||
213 | 448 | const media::Track::Id id = p.first; | 453 | const media::Track::Id id = p.first; |
214 | 449 | const bool toggle_player_state = p.second; | 454 | const bool toggle_player_state = p.second; |
215 | @@ -463,7 +468,8 @@ | |||
216 | 463 | if (toggle_player_state) | 468 | if (toggle_player_state) |
217 | 464 | d->engine->play(); | 469 | d->engine->play(); |
218 | 465 | 470 | ||
220 | 466 | d->doing_go_to_track = false; | 471 | d->doing_go_to_track.unlock(); |
221 | 472 | |||
222 | 467 | }); | 473 | }); |
223 | 468 | 474 | ||
224 | 469 | // Everything is setup, we now subscribe to death notifications. | 475 | // Everything is setup, we now subscribe to death notifications. |
225 | @@ -474,6 +480,9 @@ | |||
226 | 474 | { | 480 | { |
227 | 475 | if (auto sp = wp.lock()) | 481 | if (auto sp = wp.lock()) |
228 | 476 | { | 482 | { |
229 | 483 | if (sp->doing_abandon) | ||
230 | 484 | return; | ||
231 | 485 | |||
232 | 477 | if (died != sp->config.key) | 486 | if (died != sp->config.key) |
233 | 478 | return; | 487 | return; |
234 | 479 | 488 | ||
235 | @@ -519,6 +528,27 @@ | |||
236 | 519 | } | 528 | } |
237 | 520 | 529 | ||
238 | 521 | template<typename Parent> | 530 | template<typename Parent> |
239 | 531 | std::string media::PlayerImplementation<Parent>::uuid() const | ||
240 | 532 | { | ||
241 | 533 | // No impl for now, as not needed internally. | ||
242 | 534 | return std::string{}; | ||
243 | 535 | } | ||
244 | 536 | |||
245 | 537 | template<typename Parent> | ||
246 | 538 | void media::PlayerImplementation<Parent>::reconnect() | ||
247 | 539 | { | ||
248 | 540 | d->config.client_death_observer->register_for_death_notifications_with_key(d->config.key); | ||
249 | 541 | } | ||
250 | 542 | |||
251 | 543 | template<typename Parent> | ||
252 | 544 | void media::PlayerImplementation<Parent>::abandon() | ||
253 | 545 | { | ||
254 | 546 | // Signal client disconnection due to abandonment of player | ||
255 | 547 | d->doing_abandon = true; | ||
256 | 548 | d->on_client_died(); | ||
257 | 549 | } | ||
258 | 550 | |||
259 | 551 | template<typename Parent> | ||
260 | 522 | std::shared_ptr<media::TrackList> media::PlayerImplementation<Parent>::track_list() | 552 | std::shared_ptr<media::TrackList> media::PlayerImplementation<Parent>::track_list() |
261 | 523 | { | 553 | { |
262 | 524 | return d->track_list; | 554 | return d->track_list; |
263 | 525 | 555 | ||
264 | === modified file 'src/core/media/player_implementation.h' | |||
265 | --- src/core/media/player_implementation.h 2015-04-20 15:56:34 +0000 | |||
266 | +++ src/core/media/player_implementation.h 2015-04-20 15:56:34 +0000 | |||
267 | @@ -55,6 +55,10 @@ | |||
268 | 55 | PlayerImplementation(const Configuration& configuration); | 55 | PlayerImplementation(const Configuration& configuration); |
269 | 56 | ~PlayerImplementation(); | 56 | ~PlayerImplementation(); |
270 | 57 | 57 | ||
271 | 58 | virtual std::string uuid() const; | ||
272 | 59 | virtual void reconnect(); | ||
273 | 60 | virtual void abandon(); | ||
274 | 61 | |||
275 | 58 | virtual std::shared_ptr<TrackList> track_list(); | 62 | virtual std::shared_ptr<TrackList> track_list(); |
276 | 59 | virtual Player::PlayerKey key() const; | 63 | virtual Player::PlayerKey key() const; |
277 | 60 | 64 | ||
278 | 61 | 65 | ||
279 | === modified file 'src/core/media/player_stub.cpp' | |||
280 | --- src/core/media/player_stub.cpp 2015-04-20 15:56:34 +0000 | |||
281 | +++ src/core/media/player_stub.cpp 2015-04-20 15:56:34 +0000 | |||
282 | @@ -44,11 +44,13 @@ | |||
283 | 44 | { | 44 | { |
284 | 45 | Private(const std::shared_ptr<Service>& parent, | 45 | Private(const std::shared_ptr<Service>& parent, |
285 | 46 | const std::shared_ptr<core::dbus::Service>& service, | 46 | const std::shared_ptr<core::dbus::Service>& service, |
287 | 47 | const std::shared_ptr<core::dbus::Object>& object | 47 | const std::shared_ptr<core::dbus::Object>& object, |
288 | 48 | const std::string& uuid | ||
289 | 48 | ) : parent(parent), | 49 | ) : parent(parent), |
290 | 49 | service(service), | 50 | service(service), |
291 | 50 | object(object), | 51 | object(object), |
292 | 51 | key(object->invoke_method_synchronously<mpris::Player::Key, media::Player::PlayerKey>().value()), | 52 | key(object->invoke_method_synchronously<mpris::Player::Key, media::Player::PlayerKey>().value()), |
293 | 53 | uuid(uuid), | ||
294 | 52 | sink_factory(media::video::make_platform_default_sink_factory(key)), | 54 | sink_factory(media::video::make_platform_default_sink_factory(key)), |
295 | 53 | properties | 55 | properties |
296 | 54 | { | 56 | { |
297 | @@ -96,6 +98,7 @@ | |||
298 | 96 | dbus::Service::Ptr service; | 98 | dbus::Service::Ptr service; |
299 | 97 | dbus::Object::Ptr object; | 99 | dbus::Object::Ptr object; |
300 | 98 | media::Player::PlayerKey key; | 100 | media::Player::PlayerKey key; |
301 | 101 | std::string uuid; | ||
302 | 99 | media::video::SinkFactory sink_factory; | 102 | media::video::SinkFactory sink_factory; |
303 | 100 | struct | 103 | struct |
304 | 101 | { | 104 | { |
305 | @@ -213,8 +216,9 @@ | |||
306 | 213 | media::PlayerStub::PlayerStub( | 216 | media::PlayerStub::PlayerStub( |
307 | 214 | const std::shared_ptr<Service>& parent, | 217 | const std::shared_ptr<Service>& parent, |
308 | 215 | const std::shared_ptr<core::dbus::Service>& service, | 218 | const std::shared_ptr<core::dbus::Service>& service, |
311 | 216 | const std::shared_ptr<core::dbus::Object>& object) | 219 | const std::shared_ptr<core::dbus::Object>& object, |
312 | 217 | : d(new Private{parent, service, object}) | 220 | const std::string& uuid) |
313 | 221 | : d(new Private{parent, service, object, uuid}) | ||
314 | 218 | { | 222 | { |
315 | 219 | } | 223 | } |
316 | 220 | 224 | ||
317 | @@ -222,6 +226,21 @@ | |||
318 | 222 | { | 226 | { |
319 | 223 | } | 227 | } |
320 | 224 | 228 | ||
321 | 229 | std::string media::PlayerStub::uuid() const | ||
322 | 230 | { | ||
323 | 231 | return d->uuid; | ||
324 | 232 | } | ||
325 | 233 | |||
326 | 234 | void media::PlayerStub::reconnect() | ||
327 | 235 | { | ||
328 | 236 | // No implementation | ||
329 | 237 | } | ||
330 | 238 | |||
331 | 239 | void media::PlayerStub::abandon() | ||
332 | 240 | { | ||
333 | 241 | // No implementation | ||
334 | 242 | } | ||
335 | 243 | |||
336 | 225 | std::shared_ptr<media::TrackList> media::PlayerStub::track_list() | 244 | std::shared_ptr<media::TrackList> media::PlayerStub::track_list() |
337 | 226 | { | 245 | { |
338 | 227 | if (!d->track_list) | 246 | if (!d->track_list) |
339 | 228 | 247 | ||
340 | === modified file 'src/core/media/player_stub.h' | |||
341 | --- src/core/media/player_stub.h 2015-04-20 15:56:34 +0000 | |||
342 | +++ src/core/media/player_stub.h 2015-04-20 15:56:34 +0000 | |||
343 | @@ -40,10 +40,15 @@ | |||
344 | 40 | explicit PlayerStub( | 40 | explicit PlayerStub( |
345 | 41 | const std::shared_ptr<Service>& parent, | 41 | const std::shared_ptr<Service>& parent, |
346 | 42 | const std::shared_ptr<core::dbus::Service>& service, | 42 | const std::shared_ptr<core::dbus::Service>& service, |
348 | 43 | const std::shared_ptr<core::dbus::Object>& object); | 43 | const std::shared_ptr<core::dbus::Object>& object, |
349 | 44 | const std::string& uuid = std::string{}); | ||
350 | 44 | 45 | ||
351 | 45 | ~PlayerStub(); | 46 | ~PlayerStub(); |
352 | 46 | 47 | ||
353 | 48 | virtual std::string uuid() const; | ||
354 | 49 | virtual void reconnect(); | ||
355 | 50 | virtual void abandon(); | ||
356 | 51 | |||
357 | 47 | virtual std::shared_ptr<TrackList> track_list(); | 52 | virtual std::shared_ptr<TrackList> track_list(); |
358 | 48 | virtual PlayerKey key() const; | 53 | virtual PlayerKey key() const; |
359 | 49 | 54 | ||
360 | 50 | 55 | ||
361 | === modified file 'src/core/media/server/server.cpp' | |||
362 | --- src/core/media/server/server.cpp 2014-12-15 14:43:44 +0000 | |||
363 | +++ src/core/media/server/server.cpp 2015-04-20 15:56:34 +0000 | |||
364 | @@ -123,7 +123,7 @@ | |||
365 | 123 | { | 123 | { |
366 | 124 | impl, | 124 | impl, |
367 | 125 | player_store, | 125 | player_store, |
369 | 126 | 126 | external_services | |
370 | 127 | }); | 127 | }); |
371 | 128 | 128 | ||
372 | 129 | std::thread service_worker | 129 | std::thread service_worker |
373 | 130 | 130 | ||
374 | === modified file 'src/core/media/service_implementation.cpp' | |||
375 | --- src/core/media/service_implementation.cpp 2015-04-20 15:56:34 +0000 | |||
376 | +++ src/core/media/service_implementation.cpp 2015-04-20 15:56:34 +0000 | |||
377 | @@ -218,6 +218,22 @@ | |||
378 | 218 | return player; | 218 | return player; |
379 | 219 | } | 219 | } |
380 | 220 | 220 | ||
381 | 221 | void media::ServiceImplementation::detach_session(const std::string&, const media::Player::Configuration&) | ||
382 | 222 | { | ||
383 | 223 | // no impl | ||
384 | 224 | } | ||
385 | 225 | |||
386 | 226 | std::shared_ptr<media::Player> media::ServiceImplementation::reattach_session(const std::string&, const media::Player::Configuration&) | ||
387 | 227 | { | ||
388 | 228 | // no impl | ||
389 | 229 | return std::shared_ptr<media::Player>(); | ||
390 | 230 | } | ||
391 | 231 | |||
392 | 232 | void media::ServiceImplementation::destroy_session(const std::string&, const media::Player::Configuration&) | ||
393 | 233 | { | ||
394 | 234 | // no impl | ||
395 | 235 | } | ||
396 | 236 | |||
397 | 221 | std::shared_ptr<media::Player> media::ServiceImplementation::create_fixed_session(const std::string&, const media::Player::Configuration&) | 237 | std::shared_ptr<media::Player> media::ServiceImplementation::create_fixed_session(const std::string&, const media::Player::Configuration&) |
398 | 222 | { | 238 | { |
399 | 223 | // no impl | 239 | // no impl |
400 | 224 | 240 | ||
401 | === modified file 'src/core/media/service_implementation.h' | |||
402 | --- src/core/media/service_implementation.h 2015-04-02 14:46:52 +0000 | |||
403 | +++ src/core/media/service_implementation.h 2015-04-20 15:56:34 +0000 | |||
404 | @@ -44,6 +44,9 @@ | |||
405 | 44 | ~ServiceImplementation (); | 44 | ~ServiceImplementation (); |
406 | 45 | 45 | ||
407 | 46 | std::shared_ptr<Player> create_session(const Player::Configuration&); | 46 | std::shared_ptr<Player> create_session(const Player::Configuration&); |
408 | 47 | void detach_session(const std::string&, const Player::Configuration&); | ||
409 | 48 | std::shared_ptr<Player> reattach_session(const std::string&, const Player::Configuration&); | ||
410 | 49 | void destroy_session(const std::string&, const Player::Configuration&); | ||
411 | 47 | 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&); |
412 | 48 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); | 51 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); |
413 | 49 | void pause_other_sessions(Player::PlayerKey key); | 52 | void pause_other_sessions(Player::PlayerKey key); |
414 | 50 | 53 | ||
415 | === modified file 'src/core/media/service_skeleton.cpp' | |||
416 | --- src/core/media/service_skeleton.cpp 2015-04-20 15:56:34 +0000 | |||
417 | +++ src/core/media/service_skeleton.cpp 2015-04-20 15:56:34 +0000 | |||
418 | @@ -35,6 +35,10 @@ | |||
419 | 35 | 35 | ||
420 | 36 | #include <core/posix/this_process.h> | 36 | #include <core/posix/this_process.h> |
421 | 37 | 37 | ||
422 | 38 | #include <boost/uuid/uuid.hpp> | ||
423 | 39 | #include <boost/uuid/uuid_generators.hpp> | ||
424 | 40 | #include <boost/uuid/uuid_io.hpp> | ||
425 | 41 | |||
426 | 38 | #include <map> | 42 | #include <map> |
427 | 39 | #include <regex> | 43 | #include <regex> |
428 | 40 | #include <sstream> | 44 | #include <sstream> |
429 | @@ -50,17 +54,33 @@ | |||
430 | 50 | struct media::ServiceSkeleton::Private | 54 | struct media::ServiceSkeleton::Private |
431 | 51 | { | 55 | { |
432 | 52 | Private(media::ServiceSkeleton* impl, const ServiceSkeleton::Configuration& config) | 56 | Private(media::ServiceSkeleton* impl, const ServiceSkeleton::Configuration& config) |
434 | 53 | : impl(impl), | 57 | : request_context_resolver(media::apparmor::ubuntu::make_platform_default_request_context_resolver(config.external_services)), |
435 | 58 | impl(impl), | ||
436 | 54 | object(impl->access_service()->add_object_for_path( | 59 | object(impl->access_service()->add_object_for_path( |
437 | 55 | dbus::traits::Service<media::Service>::object_path())), | 60 | dbus::traits::Service<media::Service>::object_path())), |
440 | 56 | exported(impl->access_bus(), config.cover_art_resolver), | 61 | configuration(config), |
441 | 57 | configuration(config) | 62 | exported(impl->access_bus(), config.cover_art_resolver) |
442 | 58 | { | 63 | { |
443 | 59 | object->install_method_handler<mpris::Service::CreateSession>( | 64 | object->install_method_handler<mpris::Service::CreateSession>( |
444 | 60 | std::bind( | 65 | std::bind( |
445 | 61 | &Private::handle_create_session, | 66 | &Private::handle_create_session, |
446 | 62 | this, | 67 | this, |
447 | 63 | std::placeholders::_1)); | 68 | std::placeholders::_1)); |
448 | 69 | object->install_method_handler<mpris::Service::DetachSession>( | ||
449 | 70 | std::bind( | ||
450 | 71 | &Private::handle_detach_session, | ||
451 | 72 | this, | ||
452 | 73 | std::placeholders::_1)); | ||
453 | 74 | object->install_method_handler<mpris::Service::ReattachSession>( | ||
454 | 75 | std::bind( | ||
455 | 76 | &Private::handle_reattach_session, | ||
456 | 77 | this, | ||
457 | 78 | std::placeholders::_1)); | ||
458 | 79 | object->install_method_handler<mpris::Service::DestroySession>( | ||
459 | 80 | std::bind( | ||
460 | 81 | &Private::handle_destroy_session, | ||
461 | 82 | this, | ||
462 | 83 | std::placeholders::_1)); | ||
463 | 64 | object->install_method_handler<mpris::Service::CreateFixedSession>( | 84 | object->install_method_handler<mpris::Service::CreateFixedSession>( |
464 | 65 | std::bind( | 85 | std::bind( |
465 | 66 | &Private::handle_create_fixed_session, | 86 | &Private::handle_create_fixed_session, |
466 | @@ -78,24 +98,26 @@ | |||
467 | 78 | std::placeholders::_1)); | 98 | std::placeholders::_1)); |
468 | 79 | } | 99 | } |
469 | 80 | 100 | ||
471 | 81 | std::pair<std::string, media::Player::PlayerKey> create_session_info() | 101 | std::tuple<std::string, media::Player::PlayerKey, std::string> create_session_info() |
472 | 82 | { | 102 | { |
473 | 83 | static unsigned int session_counter = 0; | 103 | static unsigned int session_counter = 0; |
474 | 84 | 104 | ||
475 | 85 | unsigned int current_session = session_counter++; | 105 | unsigned int current_session = session_counter++; |
476 | 106 | boost::uuids::uuid uuid = gen(); | ||
477 | 86 | 107 | ||
478 | 87 | std::stringstream ss; | 108 | std::stringstream ss; |
479 | 88 | ss << "/core/ubuntu/media/Service/sessions/" << current_session; | 109 | ss << "/core/ubuntu/media/Service/sessions/" << current_session; |
480 | 89 | 110 | ||
482 | 90 | return std::make_pair(ss.str(), media::Player::PlayerKey(current_session)); | 111 | return std::make_tuple(ss.str(), media::Player::PlayerKey(current_session), to_string(uuid)); |
483 | 91 | } | 112 | } |
484 | 92 | 113 | ||
485 | 93 | void handle_create_session(const core::dbus::Message::Ptr& msg) | 114 | void handle_create_session(const core::dbus::Message::Ptr& msg) |
486 | 94 | { | 115 | { |
488 | 95 | auto session_info = create_session_info(); | 116 | auto session_info = create_session_info(); |
489 | 96 | 117 | ||
492 | 97 | dbus::types::ObjectPath op{session_info.first}; | 118 | dbus::types::ObjectPath op{std::get<0>(session_info)}; |
493 | 98 | media::Player::PlayerKey key{session_info.second}; | 119 | media::Player::PlayerKey key{std::get<1>(session_info)}; |
494 | 120 | std::string uuid{std::get<2>(session_info)}; | ||
495 | 99 | 121 | ||
496 | 100 | media::Player::Configuration config | 122 | media::Player::Configuration config |
497 | 101 | { | 123 | { |
498 | @@ -105,11 +127,21 @@ | |||
499 | 105 | impl->access_service()->add_object_for_path(op) | 127 | impl->access_service()->add_object_for_path(op) |
500 | 106 | }; | 128 | }; |
501 | 107 | 129 | ||
502 | 130 | std::cout << "Session created by request of: " << msg->sender() << ", uuid: " << uuid << ", path:" << op << std::endl; | ||
503 | 131 | |||
504 | 108 | try | 132 | try |
505 | 109 | { | 133 | { |
506 | 110 | configuration.player_store->add_player_for_key(key, impl->create_session(config)); | 134 | configuration.player_store->add_player_for_key(key, impl->create_session(config)); |
507 | 135 | uuid_player_map.insert(std::make_pair(uuid, key)); | ||
508 | 136 | |||
509 | 137 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, key, msg](const media::apparmor::ubuntu::Context& context) | ||
510 | 138 | { | ||
511 | 139 | fprintf(stderr, "%s():%d -- app_name='%s', attached\n", __func__, __LINE__, context.str().c_str()); | ||
512 | 140 | player_owner_map.insert(std::make_pair(key, std::make_tuple(context.str(), true, msg->sender()))); | ||
513 | 141 | }); | ||
514 | 142 | |||
515 | 111 | auto reply = dbus::Message::make_method_return(msg); | 143 | auto reply = dbus::Message::make_method_return(msg); |
517 | 112 | reply->writer() << op; | 144 | reply->writer() << std::make_tuple(op, uuid); |
518 | 113 | 145 | ||
519 | 114 | impl->access_bus()->send(reply); | 146 | impl->access_bus()->send(reply); |
520 | 115 | } catch(const std::runtime_error& e) | 147 | } catch(const std::runtime_error& e) |
521 | @@ -122,6 +154,174 @@ | |||
522 | 122 | } | 154 | } |
523 | 123 | } | 155 | } |
524 | 124 | 156 | ||
525 | 157 | void handle_detach_session(const core::dbus::Message::Ptr& msg) | ||
526 | 158 | { | ||
527 | 159 | try | ||
528 | 160 | { | ||
529 | 161 | std::string uuid; | ||
530 | 162 | msg->reader() >> uuid; | ||
531 | 163 | |||
532 | 164 | auto key = uuid_player_map.at(uuid); | ||
533 | 165 | |||
534 | 166 | if (player_owner_map.count(key) != 0) { | ||
535 | 167 | auto info = player_owner_map.at(key); | ||
536 | 168 | // Check if session is attached(1) and that the detachment | ||
537 | 169 | // request comes from the same peer(2) that created the session. | ||
538 | 170 | if (std::get<1>(info) && (std::get<2>(info) == msg->sender())) { // Player is attached | ||
539 | 171 | std::get<1>(info) = false; // Detached | ||
540 | 172 | std::get<2>(info).clear(); // Clear registered sender/peer | ||
541 | 173 | auto player = configuration.player_store->player_for_key(key); | ||
542 | 174 | player->lifetime().set(media::Player::Lifetime::resumable); | ||
543 | 175 | } | ||
544 | 176 | } | ||
545 | 177 | |||
546 | 178 | auto reply = dbus::Message::make_method_return(msg); | ||
547 | 179 | impl->access_bus()->send(reply); | ||
548 | 180 | |||
549 | 181 | } catch(const std::runtime_error& e) | ||
550 | 182 | { | ||
551 | 183 | auto reply = dbus::Message::make_error( | ||
552 | 184 | msg, | ||
553 | 185 | mpris::Service::Errors::DetachingSession::name(), | ||
554 | 186 | e.what()); | ||
555 | 187 | impl->access_bus()->send(reply); | ||
556 | 188 | } | ||
557 | 189 | } | ||
558 | 190 | |||
559 | 191 | void handle_reattach_session(const core::dbus::Message::Ptr& msg) | ||
560 | 192 | { | ||
561 | 193 | try | ||
562 | 194 | { | ||
563 | 195 | std::string uuid; | ||
564 | 196 | msg->reader() >> uuid; | ||
565 | 197 | |||
566 | 198 | if (uuid_player_map.count(uuid) != 0) { | ||
567 | 199 | auto key = uuid_player_map.at(uuid); | ||
568 | 200 | if (not configuration.player_store->has_player_for_key(key)) { | ||
569 | 201 | auto reply = dbus::Message::make_error( | ||
570 | 202 | msg, | ||
571 | 203 | mpris::Service::Errors::ReattachingSession::name(), | ||
572 | 204 | "Unable to locate player session"); | ||
573 | 205 | impl->access_bus()->send(reply); | ||
574 | 206 | return; | ||
575 | 207 | } | ||
576 | 208 | std::stringstream ss; | ||
577 | 209 | ss << "/core/ubuntu/media/Service/sessions/" << key; | ||
578 | 210 | dbus::types::ObjectPath op{ss.str()}; | ||
579 | 211 | |||
580 | 212 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, msg, key, op](const media::apparmor::ubuntu::Context& context) | ||
581 | 213 | { | ||
582 | 214 | auto info = player_owner_map.at(key); | ||
583 | 215 | 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()); | ||
584 | 216 | if (std::get<0>(info) == context.str()) { | ||
585 | 217 | std::get<1>(info) = true; // Set to Attached | ||
586 | 218 | std::get<2>(info) = msg->sender(); // Register new owner | ||
587 | 219 | |||
588 | 220 | // Signal player reconnection | ||
589 | 221 | auto player = configuration.player_store->player_for_key(key); | ||
590 | 222 | player->reconnect(); | ||
591 | 223 | |||
592 | 224 | auto reply = dbus::Message::make_method_return(msg); | ||
593 | 225 | reply->writer() << op; | ||
594 | 226 | |||
595 | 227 | impl->access_bus()->send(reply); | ||
596 | 228 | } | ||
597 | 229 | else { | ||
598 | 230 | auto reply = dbus::Message::make_error( | ||
599 | 231 | msg, | ||
600 | 232 | mpris::Service::Errors::ReattachingSession::name(), | ||
601 | 233 | "Invalid permissions for the requested session"); | ||
602 | 234 | impl->access_bus()->send(reply); | ||
603 | 235 | return; | ||
604 | 236 | } | ||
605 | 237 | }); | ||
606 | 238 | } | ||
607 | 239 | else { | ||
608 | 240 | auto reply = dbus::Message::make_error( | ||
609 | 241 | msg, | ||
610 | 242 | mpris::Service::Errors::ReattachingSession::name(), | ||
611 | 243 | "Invalid session"); | ||
612 | 244 | impl->access_bus()->send(reply); | ||
613 | 245 | return; | ||
614 | 246 | } | ||
615 | 247 | } catch(const std::runtime_error& e) | ||
616 | 248 | { | ||
617 | 249 | auto reply = dbus::Message::make_error( | ||
618 | 250 | msg, | ||
619 | 251 | mpris::Service::Errors::ReattachingSession::name(), | ||
620 | 252 | e.what()); | ||
621 | 253 | impl->access_bus()->send(reply); | ||
622 | 254 | } | ||
623 | 255 | } | ||
624 | 256 | |||
625 | 257 | void handle_destroy_session(const core::dbus::Message::Ptr& msg) | ||
626 | 258 | { | ||
627 | 259 | |||
628 | 260 | try | ||
629 | 261 | { | ||
630 | 262 | std::string uuid; | ||
631 | 263 | msg->reader() >> uuid; | ||
632 | 264 | |||
633 | 265 | if (uuid_player_map.count(uuid) != 0) { | ||
634 | 266 | auto key = uuid_player_map.at(uuid); | ||
635 | 267 | if (not configuration.player_store->has_player_for_key(key)) { | ||
636 | 268 | auto reply = dbus::Message::make_error( | ||
637 | 269 | msg, | ||
638 | 270 | mpris::Service::Errors::DestroyingSession::name(), | ||
639 | 271 | "Unable to locate player session"); | ||
640 | 272 | impl->access_bus()->send(reply); | ||
641 | 273 | return; | ||
642 | 274 | } | ||
643 | 275 | |||
644 | 276 | // Remove control entries from the map, at this point | ||
645 | 277 | // the session is no longer usable. | ||
646 | 278 | uuid_player_map.erase(uuid); | ||
647 | 279 | |||
648 | 280 | request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [this, msg, key](const media::apparmor::ubuntu::Context& context) | ||
649 | 281 | { | ||
650 | 282 | auto info = player_owner_map.at(key); | ||
651 | 283 | 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()); | ||
652 | 284 | if (std::get<0>(info) == context.str()) { | ||
653 | 285 | player_owner_map.erase(key); | ||
654 | 286 | |||
655 | 287 | // Reset lifecycle to non-resumable on the now-abandoned session | ||
656 | 288 | auto player = configuration.player_store->player_for_key(key); | ||
657 | 289 | |||
658 | 290 | // Delete player instance by abandonment | ||
659 | 291 | player->lifetime().set(media::Player::Lifetime::normal); | ||
660 | 292 | player->abandon(); | ||
661 | 293 | |||
662 | 294 | auto reply = dbus::Message::make_method_return(msg); | ||
663 | 295 | impl->access_bus()->send(reply); | ||
664 | 296 | } | ||
665 | 297 | else { | ||
666 | 298 | auto reply = dbus::Message::make_error( | ||
667 | 299 | msg, | ||
668 | 300 | mpris::Service::Errors::DestroyingSession::name(), | ||
669 | 301 | "Invalid permissions for the requested session"); | ||
670 | 302 | impl->access_bus()->send(reply); | ||
671 | 303 | return; | ||
672 | 304 | } | ||
673 | 305 | }); | ||
674 | 306 | } | ||
675 | 307 | else { | ||
676 | 308 | auto reply = dbus::Message::make_error( | ||
677 | 309 | msg, | ||
678 | 310 | mpris::Service::Errors::DestroyingSession::name(), | ||
679 | 311 | "Invalid session"); | ||
680 | 312 | impl->access_bus()->send(reply); | ||
681 | 313 | return; | ||
682 | 314 | } | ||
683 | 315 | } catch(const std::runtime_error& e) | ||
684 | 316 | { | ||
685 | 317 | auto reply = dbus::Message::make_error( | ||
686 | 318 | msg, | ||
687 | 319 | mpris::Service::Errors::DestroyingSession::name(), | ||
688 | 320 | e.what()); | ||
689 | 321 | impl->access_bus()->send(reply); | ||
690 | 322 | } | ||
691 | 323 | } | ||
692 | 324 | |||
693 | 125 | void handle_create_fixed_session(const core::dbus::Message::Ptr& msg) | 325 | void handle_create_fixed_session(const core::dbus::Message::Ptr& msg) |
694 | 126 | { | 326 | { |
695 | 127 | try | 327 | try |
696 | @@ -133,8 +333,8 @@ | |||
697 | 133 | // Create new session | 333 | // Create new session |
698 | 134 | auto session_info = create_session_info(); | 334 | auto session_info = create_session_info(); |
699 | 135 | 335 | ||
702 | 136 | dbus::types::ObjectPath op{session_info.first}; | 336 | dbus::types::ObjectPath op{std::get<0>(session_info)}; |
703 | 137 | media::Player::PlayerKey key{session_info.second}; | 337 | media::Player::PlayerKey key{std::get<1>(session_info)}; |
704 | 138 | 338 | ||
705 | 139 | media::Player::Configuration config | 339 | media::Player::Configuration config |
706 | 140 | { | 340 | { |
707 | @@ -149,7 +349,6 @@ | |||
708 | 149 | 349 | ||
709 | 150 | configuration.player_store->add_player_for_key(key, session); | 350 | configuration.player_store->add_player_for_key(key, session); |
710 | 151 | 351 | ||
711 | 152 | |||
712 | 153 | named_player_map.insert(std::make_pair(name, key)); | 352 | named_player_map.insert(std::make_pair(name, key)); |
713 | 154 | 353 | ||
714 | 155 | auto reply = dbus::Message::make_method_return(msg); | 354 | auto reply = dbus::Message::make_method_return(msg); |
715 | @@ -233,6 +432,7 @@ | |||
716 | 233 | impl->access_bus()->send(reply); | 432 | impl->access_bus()->send(reply); |
717 | 234 | } | 433 | } |
718 | 235 | 434 | ||
719 | 435 | media::apparmor::ubuntu::RequestContextResolver::Ptr request_context_resolver; | ||
720 | 236 | media::ServiceSkeleton* impl; | 436 | media::ServiceSkeleton* impl; |
721 | 237 | dbus::Object::Ptr object; | 437 | dbus::Object::Ptr object; |
722 | 238 | 438 | ||
723 | @@ -240,6 +440,14 @@ | |||
724 | 240 | ServiceSkeleton::Configuration configuration; | 440 | ServiceSkeleton::Configuration configuration; |
725 | 241 | // We map named/fixed player instances to their respective keys. | 441 | // We map named/fixed player instances to their respective keys. |
726 | 242 | std::map<std::string, media::Player::PlayerKey> named_player_map; | 442 | std::map<std::string, media::Player::PlayerKey> named_player_map; |
727 | 443 | // We map UUIDs to their respective keys. | ||
728 | 444 | std::map<std::string, media::Player::PlayerKey> uuid_player_map; | ||
729 | 445 | // We keep a list of keys and their respective owners and states. | ||
730 | 446 | // value: (owner context, attached state, attached dbus name) | ||
731 | 447 | std::map<media::Player::PlayerKey, std::tuple<std::string, bool, std::string>> player_owner_map; | ||
732 | 448 | |||
733 | 449 | boost::uuids::random_generator gen; | ||
734 | 450 | |||
735 | 243 | // We expose the entire service as an MPRIS player. | 451 | // We expose the entire service as an MPRIS player. |
736 | 244 | struct Exported | 452 | struct Exported |
737 | 245 | { | 453 | { |
738 | @@ -527,6 +735,21 @@ | |||
739 | 527 | return d->configuration.impl->create_session(config); | 735 | return d->configuration.impl->create_session(config); |
740 | 528 | } | 736 | } |
741 | 529 | 737 | ||
742 | 738 | void media::ServiceSkeleton::detach_session(const std::string& uuid, const media::Player::Configuration& config) | ||
743 | 739 | { | ||
744 | 740 | return d->configuration.impl->detach_session(uuid, config); | ||
745 | 741 | } | ||
746 | 742 | |||
747 | 743 | std::shared_ptr<media::Player> media::ServiceSkeleton::reattach_session(const std::string& uuid, const media::Player::Configuration& config) | ||
748 | 744 | { | ||
749 | 745 | return d->configuration.impl->reattach_session(uuid, config); | ||
750 | 746 | } | ||
751 | 747 | |||
752 | 748 | void media::ServiceSkeleton::destroy_session(const std::string& uuid, const media::Player::Configuration& config) | ||
753 | 749 | { | ||
754 | 750 | return d->configuration.impl->destroy_session(uuid, config); | ||
755 | 751 | } | ||
756 | 752 | |||
757 | 530 | std::shared_ptr<media::Player> media::ServiceSkeleton::create_fixed_session(const std::string& name, const media::Player::Configuration&config) | 753 | std::shared_ptr<media::Player> media::ServiceSkeleton::create_fixed_session(const std::string& name, const media::Player::Configuration&config) |
758 | 531 | { | 754 | { |
759 | 532 | return d->configuration.impl->create_fixed_session(name, config); | 755 | return d->configuration.impl->create_fixed_session(name, config); |
760 | 533 | 756 | ||
761 | === modified file 'src/core/media/service_skeleton.h' | |||
762 | --- src/core/media/service_skeleton.h 2014-12-15 14:43:44 +0000 | |||
763 | +++ src/core/media/service_skeleton.h 2015-04-20 15:56:34 +0000 | |||
764 | @@ -19,6 +19,8 @@ | |||
765 | 19 | #ifndef CORE_UBUNTU_MEDIA_SERVICE_SKELETON_H_ | 19 | #ifndef CORE_UBUNTU_MEDIA_SERVICE_SKELETON_H_ |
766 | 20 | #define CORE_UBUNTU_MEDIA_SERVICE_SKELETON_H_ | 20 | #define CORE_UBUNTU_MEDIA_SERVICE_SKELETON_H_ |
767 | 21 | 21 | ||
768 | 22 | #include "apparmor/ubuntu.h" | ||
769 | 23 | |||
770 | 22 | #include <core/media/service.h> | 24 | #include <core/media/service.h> |
771 | 23 | 25 | ||
772 | 24 | #include "cover_art_resolver.h" | 26 | #include "cover_art_resolver.h" |
773 | @@ -43,6 +45,7 @@ | |||
774 | 43 | { | 45 | { |
775 | 44 | std::shared_ptr<Service> impl; | 46 | std::shared_ptr<Service> impl; |
776 | 45 | KeyedPlayerStore::Ptr player_store; | 47 | KeyedPlayerStore::Ptr player_store; |
777 | 48 | helper::ExternalServices& external_services; | ||
778 | 46 | CoverArtResolver cover_art_resolver; | 49 | CoverArtResolver cover_art_resolver; |
779 | 47 | }; | 50 | }; |
780 | 48 | 51 | ||
781 | @@ -51,6 +54,9 @@ | |||
782 | 51 | 54 | ||
783 | 52 | // From media::Service | 55 | // From media::Service |
784 | 53 | std::shared_ptr<Player> create_session(const Player::Configuration&); | 56 | std::shared_ptr<Player> create_session(const Player::Configuration&); |
785 | 57 | void detach_session(const std::string&, const Player::Configuration&); | ||
786 | 58 | std::shared_ptr<Player> reattach_session(const std::string&, const Player::Configuration&); | ||
787 | 59 | void destroy_session(const std::string&, const media::Player::Configuration&); | ||
788 | 54 | 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&); |
789 | 55 | std::shared_ptr<Player> resume_session(Player::PlayerKey); | 61 | std::shared_ptr<Player> resume_session(Player::PlayerKey); |
790 | 56 | void pause_other_sessions(Player::PlayerKey key); | 62 | void pause_other_sessions(Player::PlayerKey key); |
791 | 57 | 63 | ||
792 | === modified file 'src/core/media/service_stub.cpp' | |||
793 | --- src/core/media/service_stub.cpp 2015-04-20 15:56:34 +0000 | |||
794 | +++ src/core/media/service_stub.cpp 2015-04-20 15:56:34 +0000 | |||
795 | @@ -58,7 +58,7 @@ | |||
796 | 58 | std::shared_ptr<media::Player> media::ServiceStub::create_session(const media::Player::Configuration&) | 58 | std::shared_ptr<media::Player> media::ServiceStub::create_session(const media::Player::Configuration&) |
797 | 59 | { | 59 | { |
798 | 60 | auto op = d->object->invoke_method_synchronously<mpris::Service::CreateSession, | 60 | auto op = d->object->invoke_method_synchronously<mpris::Service::CreateSession, |
800 | 61 | dbus::types::ObjectPath>(); | 61 | std::tuple<dbus::types::ObjectPath, std::string>>(); |
801 | 62 | 62 | ||
802 | 63 | if (op.is_error()) | 63 | if (op.is_error()) |
803 | 64 | throw std::runtime_error("Problem creating session: " + op.error()); | 64 | throw std::runtime_error("Problem creating session: " + op.error()); |
804 | @@ -67,8 +67,44 @@ | |||
805 | 67 | { | 67 | { |
806 | 68 | shared_from_this(), | 68 | shared_from_this(), |
807 | 69 | access_service(), | 69 | access_service(), |
810 | 70 | access_service()->object_for_path(op.value()) | 70 | access_service()->object_for_path(std::get<0>(op.value())), |
811 | 71 | }); | 71 | std::get<1>(op.value()) |
812 | 72 | }); | ||
813 | 73 | } | ||
814 | 74 | |||
815 | 75 | void media::ServiceStub::detach_session(const std::string& uuid, const media::Player::Configuration&) | ||
816 | 76 | { | ||
817 | 77 | auto op = d->object->invoke_method_synchronously<mpris::Service::DetachSession, | ||
818 | 78 | void>(uuid); | ||
819 | 79 | |||
820 | 80 | if (op.is_error()) | ||
821 | 81 | throw std::runtime_error("Problem detaching session: " + op.error()); | ||
822 | 82 | } | ||
823 | 83 | |||
824 | 84 | std::shared_ptr<media::Player> media::ServiceStub::reattach_session(const std::string& uuid, const media::Player::Configuration&) | ||
825 | 85 | { | ||
826 | 86 | auto op = d->object->invoke_method_synchronously<mpris::Service::ReattachSession, | ||
827 | 87 | dbus::types::ObjectPath>(uuid); | ||
828 | 88 | |||
829 | 89 | if (op.is_error()) | ||
830 | 90 | throw std::runtime_error("Problem reattaching session: " + op.error()); | ||
831 | 91 | |||
832 | 92 | return std::shared_ptr<media::Player>(new media::PlayerStub | ||
833 | 93 | { | ||
834 | 94 | shared_from_this(), | ||
835 | 95 | access_service(), | ||
836 | 96 | access_service()->object_for_path(op.value()), | ||
837 | 97 | uuid | ||
838 | 98 | }); | ||
839 | 99 | } | ||
840 | 100 | |||
841 | 101 | void media::ServiceStub::destroy_session(const std::string& uuid, const media::Player::Configuration&) | ||
842 | 102 | { | ||
843 | 103 | auto op = d->object->invoke_method_synchronously<mpris::Service::DestroySession, | ||
844 | 104 | void>(uuid); | ||
845 | 105 | |||
846 | 106 | if (op.is_error()) | ||
847 | 107 | throw std::runtime_error("Problem destroying session: " + op.error()); | ||
848 | 72 | } | 108 | } |
849 | 73 | 109 | ||
850 | 74 | std::shared_ptr<media::Player> media::ServiceStub::create_fixed_session(const std::string& name, const media::Player::Configuration&) | 110 | std::shared_ptr<media::Player> media::ServiceStub::create_fixed_session(const std::string& name, const media::Player::Configuration&) |
851 | 75 | 111 | ||
852 | === modified file 'src/core/media/service_stub.h' | |||
853 | --- src/core/media/service_stub.h 2014-10-23 14:42:59 +0000 | |||
854 | +++ src/core/media/service_stub.h 2015-04-20 15:56:34 +0000 | |||
855 | @@ -40,6 +40,9 @@ | |||
856 | 40 | ~ServiceStub(); | 40 | ~ServiceStub(); |
857 | 41 | 41 | ||
858 | 42 | std::shared_ptr<Player> create_session(const Player::Configuration&); | 42 | std::shared_ptr<Player> create_session(const Player::Configuration&); |
859 | 43 | void detach_session(const std::string& uuid, const Player::Configuration&); | ||
860 | 44 | std::shared_ptr<Player> reattach_session(const std::string& uuid, const Player::Configuration&); | ||
861 | 45 | void destroy_session(const std::string& uuid, const Player::Configuration&); | ||
862 | 43 | 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&); |
863 | 44 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); | 47 | std::shared_ptr<Player> resume_session(Player::PlayerKey key); |
864 | 45 | void pause_other_sessions(Player::PlayerKey key); | 48 | void pause_other_sessions(Player::PlayerKey key); |
865 | 46 | 49 | ||
866 | === modified file 'tests/test-track-list/test_track_list.cpp' | |||
867 | --- tests/test-track-list/test_track_list.cpp 2015-04-20 15:56:34 +0000 | |||
868 | +++ tests/test-track-list/test_track_list.cpp 2015-04-20 15:56:34 +0000 | |||
869 | @@ -44,7 +44,7 @@ | |||
870 | 44 | { | 44 | { |
871 | 45 | } | 45 | } |
872 | 46 | 46 | ||
874 | 47 | void media::TestTrackList::create_new_player_session() | 47 | std::string media::TestTrackList::create_new_player_session() |
875 | 48 | { | 48 | { |
876 | 49 | try { | 49 | try { |
877 | 50 | m_hubPlayerSession = m_hubService->create_session(media::Player::Client::default_configuration()); | 50 | m_hubPlayerSession = m_hubService->create_session(media::Player::Client::default_configuration()); |
878 | @@ -59,12 +59,53 @@ | |||
879 | 59 | catch (std::runtime_error &e) { | 59 | catch (std::runtime_error &e) { |
880 | 60 | cerr << "FATAL: Failed to retrieve the current player's TrackList: " << e.what() << endl; | 60 | cerr << "FATAL: Failed to retrieve the current player's TrackList: " << e.what() << endl; |
881 | 61 | } | 61 | } |
888 | 62 | } | 62 | |
889 | 63 | 63 | std::string uuid; | |
890 | 64 | void media::TestTrackList::destroy_player_session() | 64 | try { |
891 | 65 | { | 65 | uuid.assign(m_hubPlayerSession->uuid()); |
892 | 66 | // TODO: explicitly add a destroy session to the Service class after ricmm lands his new creation_session | 66 | } |
893 | 67 | // that returns a session ID. This will allow me to clear the tracklist after each test. | 67 | catch (std::runtime_error &e) { |
894 | 68 | cerr << "FATAL: Failed to retrieve the current player's uuid: " << e.what() << endl; | ||
895 | 69 | } | ||
896 | 70 | |||
897 | 71 | cout << "Connected to session " << uuid << endl; | ||
898 | 72 | return uuid; | ||
899 | 73 | } | ||
900 | 74 | |||
901 | 75 | void media::TestTrackList::detach_player_session(const std::string &uuid) | ||
902 | 76 | { | ||
903 | 77 | try { | ||
904 | 78 | m_hubService->detach_session(uuid, media::Player::Client::default_configuration()); | ||
905 | 79 | } | ||
906 | 80 | catch (std::runtime_error &e) { | ||
907 | 81 | cerr << "FATAL: Failed to detach the media-hub player session: " << e.what() << endl; | ||
908 | 82 | } | ||
909 | 83 | |||
910 | 84 | cout << "Detached session " << uuid << endl; | ||
911 | 85 | } | ||
912 | 86 | |||
913 | 87 | void media::TestTrackList::reattach_player_session(const std::string &uuid) | ||
914 | 88 | { | ||
915 | 89 | try { | ||
916 | 90 | m_hubPlayerSession = m_hubService->reattach_session(uuid, media::Player::Client::default_configuration()); | ||
917 | 91 | } | ||
918 | 92 | catch (std::runtime_error &e) { | ||
919 | 93 | cerr << "FATAL: Failed to reattach the media-hub player session: " << e.what() << endl; | ||
920 | 94 | } | ||
921 | 95 | |||
922 | 96 | try { | ||
923 | 97 | m_hubTrackList = m_hubPlayerSession->track_list(); | ||
924 | 98 | } | ||
925 | 99 | catch (std::runtime_error &e) { | ||
926 | 100 | cerr << "FATAL: Failed to retrieve the current player's TrackList: " << e.what() << endl; | ||
927 | 101 | } | ||
928 | 102 | |||
929 | 103 | cout << "Re-connected to session " << uuid << endl; | ||
930 | 104 | } | ||
931 | 105 | |||
932 | 106 | void media::TestTrackList::destroy_player_session(const std::string &uuid) | ||
933 | 107 | { | ||
934 | 108 | m_hubService->destroy_session(uuid, media::Player::Client::default_configuration()); | ||
935 | 68 | m_hubPlayerSession.reset(); | 109 | m_hubPlayerSession.reset(); |
936 | 69 | } | 110 | } |
937 | 70 | 111 | ||
938 | @@ -92,13 +133,13 @@ | |||
939 | 92 | { | 133 | { |
940 | 93 | cout << "--> Running test: test_basic_playback" << std::endl; | 134 | cout << "--> Running test: test_basic_playback" << std::endl; |
941 | 94 | 135 | ||
943 | 95 | core::Connection c =m_hubTrackList->on_track_added().connect([](const media::Track::Id &new_id) | 136 | const std::string uuid = create_new_player_session(); |
944 | 137 | |||
945 | 138 | core::Connection c = m_hubTrackList->on_track_added().connect([](const media::Track::Id &new_id) | ||
946 | 96 | { | 139 | { |
947 | 97 | cout << "Added track to TrackList with Id: " << new_id << endl; | 140 | cout << "Added track to TrackList with Id: " << new_id << endl; |
948 | 98 | }); | 141 | }); |
949 | 99 | 142 | ||
950 | 100 | //create_new_player_session(); | ||
951 | 101 | |||
952 | 102 | m_hubPlayerSession->open_uri(uri1); | 143 | m_hubPlayerSession->open_uri(uri1); |
953 | 103 | if (!uri2.empty()) | 144 | if (!uri2.empty()) |
954 | 104 | add_track(uri2); | 145 | add_track(uri2); |
955 | @@ -118,13 +159,34 @@ | |||
956 | 118 | 159 | ||
957 | 119 | c.disconnect(); | 160 | c.disconnect(); |
958 | 120 | 161 | ||
960 | 121 | //destroy_player_session(); | 162 | destroy_player_session(uuid); |
961 | 163 | } | ||
962 | 164 | |||
963 | 165 | void media::TestTrackList::test_tracklist_resume(const std::string &uri1, const std::string &uri2, const std::string &uuid) | ||
964 | 166 | { | ||
965 | 167 | cout << "--> Running test: test_tracklist_resume" << std::endl; | ||
966 | 168 | |||
967 | 169 | add_track(uri1); | ||
968 | 170 | add_track(uri2); | ||
969 | 171 | |||
970 | 172 | const size_t initial_size = m_hubTrackList->tracks().get().size(); | ||
971 | 173 | cout << "Tracklist size: " << initial_size << endl; | ||
972 | 174 | detach_player_session(uuid); | ||
973 | 175 | reattach_player_session(uuid); | ||
974 | 176 | cout << "Tracklist size: " << m_hubTrackList->tracks().get().size() << endl; | ||
975 | 177 | |||
976 | 178 | m_hubPlayerSession->play(); | ||
977 | 179 | |||
978 | 180 | if (initial_size != m_hubTrackList->tracks().get().size()) | ||
979 | 181 | cout << "Tracklist sizes are different, error in resuming" << endl; | ||
980 | 122 | } | 182 | } |
981 | 123 | 183 | ||
982 | 124 | void media::TestTrackList::test_ensure_tracklist_is_not_empty(const std::string &uri1, const std::string &uri2) | 184 | void media::TestTrackList::test_ensure_tracklist_is_not_empty(const std::string &uri1, const std::string &uri2) |
983 | 125 | { | 185 | { |
984 | 126 | cout << "--> Running test: test_ensure_tracklist_is_not_empty" << std::endl; | 186 | cout << "--> Running test: test_ensure_tracklist_is_not_empty" << std::endl; |
985 | 127 | 187 | ||
986 | 188 | const std::string uuid = create_new_player_session(); | ||
987 | 189 | |||
988 | 128 | add_track(uri1); | 190 | add_track(uri1); |
989 | 129 | if (!uri2.empty()) | 191 | if (!uri2.empty()) |
990 | 130 | add_track(uri2); | 192 | add_track(uri2); |
991 | @@ -133,13 +195,15 @@ | |||
992 | 133 | cout << "TrackList is not empty, test success" << endl; | 195 | cout << "TrackList is not empty, test success" << endl; |
993 | 134 | else | 196 | else |
994 | 135 | cout << "TrackList is empty, test failure" << endl; | 197 | cout << "TrackList is empty, test failure" << endl; |
995 | 198 | |||
996 | 199 | destroy_player_session(uuid); | ||
997 | 136 | } | 200 | } |
998 | 137 | 201 | ||
999 | 138 | void media::TestTrackList::test_has_next_track(const std::string &uri1, const std::string &uri2) | 202 | void media::TestTrackList::test_has_next_track(const std::string &uri1, const std::string &uri2) |
1000 | 139 | { | 203 | { |
1001 | 140 | cout << "--> Running test: test_has_next_track" << std::endl; | 204 | cout << "--> Running test: test_has_next_track" << std::endl; |
1002 | 141 | 205 | ||
1004 | 142 | //create_new_player_session(); | 206 | const std::string uuid = create_new_player_session(); |
1005 | 143 | 207 | ||
1006 | 144 | add_track(uri1); | 208 | add_track(uri1); |
1007 | 145 | add_track(uri2); | 209 | add_track(uri2); |
1008 | @@ -158,13 +222,15 @@ | |||
1009 | 158 | else | 222 | else |
1010 | 159 | cerr << "Playback did not start successfully" << endl; | 223 | cerr << "Playback did not start successfully" << endl; |
1011 | 160 | 224 | ||
1013 | 161 | //destroy_player_session(); | 225 | destroy_player_session(uuid); |
1014 | 162 | } | 226 | } |
1015 | 163 | 227 | ||
1016 | 164 | void media::TestTrackList::test_shuffle(const std::string &uri1, const std::string &uri2, const std::string &uri3) | 228 | void media::TestTrackList::test_shuffle(const std::string &uri1, const std::string &uri2, const std::string &uri3) |
1017 | 165 | { | 229 | { |
1018 | 166 | cout << "--> Running test: test_shuffle" << std::endl; | 230 | cout << "--> Running test: test_shuffle" << std::endl; |
1019 | 167 | 231 | ||
1020 | 232 | const std::string uuid = create_new_player_session(); | ||
1021 | 233 | |||
1022 | 168 | add_track(uri1); | 234 | add_track(uri1); |
1023 | 169 | add_track(uri2); | 235 | add_track(uri2); |
1024 | 170 | add_track(uri3); | 236 | add_track(uri3); |
1025 | @@ -189,22 +255,27 @@ | |||
1026 | 189 | cout << "Waiting for second track to finish playing..." << endl; | 255 | cout << "Waiting for second track to finish playing..." << endl; |
1027 | 190 | wait_for_about_to_finish(); | 256 | wait_for_about_to_finish(); |
1028 | 191 | 257 | ||
1031 | 192 | cout << "Going straight to the Track with Id of '/core/ubuntu/media/Service/sessions/0/TrackList/4'" << std::endl; | 258 | const media::Track::Id id{m_hubTrackList->tracks().get()[3]}; |
1032 | 193 | const media::Track::Id id{"/core/ubuntu/media/Service/sessions/0/TrackList/4"}; | 259 | cout << "Going straight to the Track with Id " << id << std::endl; |
1033 | 194 | const bool toggle_player_state = true; | 260 | const bool toggle_player_state = true; |
1034 | 195 | m_hubTrackList->go_to(id, toggle_player_state); | 261 | m_hubTrackList->go_to(id, toggle_player_state); |
1035 | 262 | |||
1036 | 196 | cout << "Waiting for third track to finish playing..." << endl; | 263 | cout << "Waiting for third track to finish playing..." << endl; |
1037 | 197 | wait_for_about_to_finish(); | 264 | wait_for_about_to_finish(); |
1038 | 198 | } | 265 | } |
1039 | 199 | else | 266 | else |
1040 | 200 | cerr << "Playback did not start successfully" << endl; | 267 | cerr << "Playback did not start successfully" << endl; |
1041 | 268 | |||
1042 | 269 | destroy_player_session(uuid); | ||
1043 | 201 | } | 270 | } |
1044 | 202 | 271 | ||
1045 | 203 | void media::TestTrackList::test_remove_track(const std::string &uri1, const std::string &uri2, const std::string &uri3) | 272 | void media::TestTrackList::test_remove_track(const std::string &uri1, const std::string &uri2, const std::string &uri3) |
1046 | 204 | { | 273 | { |
1047 | 205 | cout << "--> Running test: test_remove_track" << std::endl; | 274 | cout << "--> Running test: test_remove_track" << std::endl; |
1048 | 206 | 275 | ||
1050 | 207 | core::Connection c =m_hubTrackList->on_track_removed().connect([](const media::Track::Id &new_id) | 276 | const std::string uuid = create_new_player_session(); |
1051 | 277 | |||
1052 | 278 | core::Connection c = m_hubTrackList->on_track_removed().connect([](const media::Track::Id &new_id) | ||
1053 | 208 | { | 279 | { |
1054 | 209 | cout << "Removed track from TrackList with Id: " << new_id << endl; | 280 | cout << "Removed track from TrackList with Id: " << new_id << endl; |
1055 | 210 | }); | 281 | }); |
1056 | @@ -220,7 +291,8 @@ | |||
1057 | 220 | cout << "Waiting for first track to finish playing..." << endl; | 291 | cout << "Waiting for first track to finish playing..." << endl; |
1058 | 221 | wait_for_about_to_finish(); | 292 | wait_for_about_to_finish(); |
1059 | 222 | 293 | ||
1061 | 223 | const media::Track::Id id{"/core/ubuntu/media/Service/sessions/0/TrackList/1"}; | 294 | const media::Track::Id id{m_hubTrackList->tracks().get()[1]}; |
1062 | 295 | cout << "Removing Track with Id of '" << id << "'" << std::endl; | ||
1063 | 224 | m_hubTrackList->remove_track(id); | 296 | m_hubTrackList->remove_track(id); |
1064 | 225 | 297 | ||
1065 | 226 | cout << "Waiting for track after removed track to finish playing..." << endl; | 298 | cout << "Waiting for track after removed track to finish playing..." << endl; |
1066 | @@ -228,6 +300,8 @@ | |||
1067 | 228 | } | 300 | } |
1068 | 229 | else | 301 | else |
1069 | 230 | cerr << "Playback did not start successfully" << endl; | 302 | cerr << "Playback did not start successfully" << endl; |
1070 | 303 | |||
1071 | 304 | destroy_player_session(uuid); | ||
1072 | 231 | } | 305 | } |
1073 | 232 | 306 | ||
1074 | 233 | template<class T> | 307 | template<class T> |
1075 | @@ -316,26 +390,31 @@ | |||
1076 | 316 | 390 | ||
1077 | 317 | if (argc == 2) | 391 | if (argc == 2) |
1078 | 318 | { | 392 | { |
1079 | 319 | tracklist->create_new_player_session(); | ||
1080 | 320 | tracklist->test_basic_playback(argv[1]); | 393 | tracklist->test_basic_playback(argv[1]); |
1081 | 321 | tracklist->test_ensure_tracklist_is_not_empty(argv[1]); | 394 | tracklist->test_ensure_tracklist_is_not_empty(argv[1]); |
1082 | 322 | } | 395 | } |
1083 | 323 | else if (argc == 3) | 396 | else if (argc == 3) |
1084 | 324 | { | 397 | { |
1085 | 325 | tracklist->create_new_player_session(); | ||
1086 | 326 | tracklist->test_basic_playback(argv[1], argv[2]); | 398 | tracklist->test_basic_playback(argv[1], argv[2]); |
1087 | 327 | tracklist->test_ensure_tracklist_is_not_empty(argv[1], argv[2]); | 399 | tracklist->test_ensure_tracklist_is_not_empty(argv[1], argv[2]); |
1088 | 328 | tracklist->test_has_next_track(argv[1], argv[2]); | 400 | tracklist->test_has_next_track(argv[1], argv[2]); |
1089 | 329 | } | 401 | } |
1090 | 330 | else if (argc == 4) | 402 | else if (argc == 4) |
1091 | 331 | { | 403 | { |
1092 | 332 | tracklist->create_new_player_session(); | ||
1093 | 333 | tracklist->test_basic_playback(argv[1]); | 404 | tracklist->test_basic_playback(argv[1]); |
1094 | 334 | tracklist->test_ensure_tracklist_is_not_empty(argv[1], argv[2]); | 405 | tracklist->test_ensure_tracklist_is_not_empty(argv[1], argv[2]); |
1095 | 335 | tracklist->test_has_next_track(argv[1], argv[2]); | 406 | tracklist->test_has_next_track(argv[1], argv[2]); |
1096 | 336 | tracklist->test_shuffle(argv[1], argv[2], argv[3]); | 407 | tracklist->test_shuffle(argv[1], argv[2], argv[3]); |
1097 | 337 | tracklist->test_remove_track(argv[1], argv[2], argv[3]); | 408 | tracklist->test_remove_track(argv[1], argv[2], argv[3]); |
1098 | 338 | } | 409 | } |
1099 | 410 | else if (argc == 5) | ||
1100 | 411 | { | ||
1101 | 412 | std::string uuid = tracklist->create_new_player_session(); | ||
1102 | 413 | |||
1103 | 414 | tracklist->test_tracklist_resume(argv[1], argv[2], uuid); | ||
1104 | 415 | |||
1105 | 416 | tracklist->destroy_player_session(uuid); | ||
1106 | 417 | } | ||
1107 | 339 | else | 418 | else |
1108 | 340 | { | 419 | { |
1109 | 341 | cout << "Can't test TrackList, no track(s) specified." << endl; | 420 | cout << "Can't test TrackList, no track(s) specified." << endl; |
1110 | 342 | 421 | ||
1111 | === modified file 'tests/test-track-list/test_track_list.h' | |||
1112 | --- tests/test-track-list/test_track_list.h 2015-04-20 15:56:34 +0000 | |||
1113 | +++ tests/test-track-list/test_track_list.h 2015-04-20 15:56:34 +0000 | |||
1114 | @@ -45,14 +45,19 @@ | |||
1115 | 45 | TestTrackList(); | 45 | TestTrackList(); |
1116 | 46 | ~TestTrackList(); | 46 | ~TestTrackList(); |
1117 | 47 | 47 | ||
1120 | 48 | void create_new_player_session(); | 48 | std::string create_new_player_session(); |
1121 | 49 | void destroy_player_session(); | 49 | void detach_player_session(const std::string &uuid); |
1122 | 50 | void reattach_player_session(const std::string &uuid); | ||
1123 | 51 | void destroy_player_session(const std::string &uuid); | ||
1124 | 50 | 52 | ||
1125 | 51 | void add_track(const std::string &uri, bool make_current = false); | 53 | void add_track(const std::string &uri, bool make_current = false); |
1126 | 52 | 54 | ||
1127 | 53 | // Takes in one or two files for playback, adds it/them to the TrackList, and plays | 55 | // Takes in one or two files for playback, adds it/them to the TrackList, and plays |
1128 | 54 | void test_basic_playback(const std::string &uri1, const std::string &uri2 = std::string{}); | 56 | void test_basic_playback(const std::string &uri1, const std::string &uri2 = std::string{}); |
1129 | 55 | 57 | ||
1130 | 58 | // Takes two uris and confirms that they remain after a detach/reattach | ||
1131 | 59 | void test_tracklist_resume(const std::string &uri1, const std::string &uri2, const std::string &uuid); | ||
1132 | 60 | |||
1133 | 56 | void test_ensure_tracklist_is_not_empty(const std::string &uri1, const std::string &uri2 = std::string{}); | 61 | void test_ensure_tracklist_is_not_empty(const std::string &uri1, const std::string &uri2 = std::string{}); |
1134 | 57 | 62 | ||
1135 | 58 | // Takes in one or two files for playback, adds it/them to the TrackList, plays and makes sure | 63 | // Takes in one or two files for playback, adds it/them to the TrackList, plays and makes sure |
FAILED: Continuous integration, rev:139 /code.launchpad .net/~ricmm/ media-hub/ session- reattach- nonfixed/ +merge/ 256101/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ media-hub- ci/325/ jenkins. qa.ubuntu. com/job/ media-hub- vivid-amd64- ci/165/ console jenkins. qa.ubuntu. com/job/ media-hub- vivid-armhf- ci/165/ console jenkins. qa.ubuntu. com/job/ media-hub- vivid-i386- ci/165/ console
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/media- hub-ci/ 325/rebuild
http://