Merge lp:~thomas-voss/music-hub/add-backend-and-service-implementation into lp:music-hub
- add-backend-and-service-implementation
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~thomas-voss/music-hub/add-backend-and-service-implementation |
Merge into: | lp:music-hub |
Diff against target: |
7091 lines (+5910/-570) 64 files modified
CMakeLists.txt (+2/-1) debian/control (+9/-0) doc/Doxyfile.in (+1/-1) include/com/ubuntu/music/connection.h (+4/-8) include/com/ubuntu/music/player.h (+50/-55) include/com/ubuntu/music/property.h (+140/-0) include/com/ubuntu/music/service.h (+7/-6) include/com/ubuntu/music/signal.h (+149/-0) include/com/ubuntu/music/track.h (+112/-34) include/com/ubuntu/music/track_list.h (+32/-23) src/com/ubuntu/music/CMakeLists.txt (+53/-6) src/com/ubuntu/music/codec.h (+78/-0) src/com/ubuntu/music/connection.cpp (+31/-19) src/com/ubuntu/music/engine.cpp (+163/-0) src/com/ubuntu/music/engine.h (+114/-0) src/com/ubuntu/music/gstreamer/bus.h (+345/-0) src/com/ubuntu/music/gstreamer/engine.cpp (+283/-0) src/com/ubuntu/music/gstreamer/engine.h (+53/-0) src/com/ubuntu/music/gstreamer/meta_data_extractor.h (+221/-0) src/com/ubuntu/music/gstreamer/playbin.h (+219/-0) src/com/ubuntu/music/mpris/macros.h (+79/-0) src/com/ubuntu/music/mpris/player.h (+85/-0) src/com/ubuntu/music/mpris/service.h (+56/-0) src/com/ubuntu/music/mpris/track_list.h (+88/-0) src/com/ubuntu/music/player.cpp (+0/-192) src/com/ubuntu/music/player_configuration.h (+30/-0) src/com/ubuntu/music/player_implementation.cpp (+133/-0) src/com/ubuntu/music/player_implementation.h (+61/-0) src/com/ubuntu/music/player_skeleton.cpp (+325/-0) src/com/ubuntu/music/player_skeleton.h (+86/-0) src/com/ubuntu/music/player_stub.cpp (+260/-0) src/com/ubuntu/music/player_stub.h (+84/-0) src/com/ubuntu/music/player_traits.h (+50/-0) src/com/ubuntu/music/property_stub.h (+244/-0) src/com/ubuntu/music/service.cpp (+4/-17) src/com/ubuntu/music/service_implementation.cpp (+52/-0) src/com/ubuntu/music/service_implementation.h (+46/-0) src/com/ubuntu/music/service_skeleton.cpp (+111/-0) src/com/ubuntu/music/service_skeleton.h (+53/-0) src/com/ubuntu/music/service_stub.cpp (+59/-0) src/com/ubuntu/music/service_stub.h (+52/-0) src/com/ubuntu/music/service_traits.h (+60/-0) src/com/ubuntu/music/the_session_bus.cpp (+39/-0) src/com/ubuntu/music/the_session_bus.h (+26/-0) src/com/ubuntu/music/track.cpp (+7/-105) src/com/ubuntu/music/track_list.cpp (+7/-88) src/com/ubuntu/music/track_list_implementation.cpp (+116/-0) src/com/ubuntu/music/track_list_implementation.h (+54/-0) src/com/ubuntu/music/track_list_skeleton.cpp (+214/-0) src/com/ubuntu/music/track_list_skeleton.h (+67/-0) src/com/ubuntu/music/track_list_stub.cpp (+159/-0) src/com/ubuntu/music/track_list_stub.h (+67/-0) src/com/ubuntu/music/track_list_traits.h (+49/-0) tests/CMakeLists.txt (+55/-0) tests/acceptance-tests/CMakeLists.txt (+32/-0) tests/acceptance-tests/service.cpp (+220/-15) tests/cross_process_sync.cpp (+150/-0) tests/cross_process_sync.h (+58/-0) tests/fork_and_run.h (+101/-0) tests/test_data.cpp.in (+56/-0) tests/test_data.h (+30/-0) tests/unit-tests/CMakeLists.txt (+28/-0) tests/unit-tests/test-gstreamer-engine.cpp (+219/-0) tests/waitable_state_transition.h (+72/-0) |
To merge this branch: | bzr merge lp:~thomas-voss/music-hub/add-backend-and-service-implementation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
David Henningsson (community) | Needs Fixing | ||
Ubuntu Phablet Team | Pending | ||
Review via email: mp+183744@code.launchpad.net |
Commit message
Add backend and server implementation headers.
Description of the change
Add backend and server implementation headers.
PS Jenkins bot (ps-jenkins) wrote : | # |
David Henningsson (diwic) wrote : | # |
Not sure what this is supposed to add, but all files in src/com/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:10
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 11. By Thomas Voß
-
Add missing build dep on google-mock.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:11
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 12. By Thomas Voß
-
Add missing build-dependency on libgstreamer1.
0-dev.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:12
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 13. By Thomas Voß
-
Add missing build dependencies.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:13
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 14. By Thomas Voß
-
Fix build dependencies on libboost-
system- dev.
Disable two failing tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:14
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 15. By Thomas Voß
-
Add build-dependency on libboost-
program- options- dev.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:15
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 16. By Thomas Voß
-
Add fakesink for testing purposes.
- 17. By Thomas Voß
-
Ensure that the audio sink is set to a fake sink for unit testing purposes.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:17
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 17. By Thomas Voß
-
Ensure that the audio sink is set to a fake sink for unit testing purposes.
- 16. By Thomas Voß
-
Add fakesink for testing purposes.
- 15. By Thomas Voß
-
Add build-dependency on libboost-
program- options- dev. - 14. By Thomas Voß
-
Fix build dependencies on libboost-
system- dev.
Disable two failing tests. - 13. By Thomas Voß
-
Add missing build dependencies.
- 12. By Thomas Voß
-
Add missing build-dependency on libgstreamer1.
0-dev. - 11. By Thomas Voß
-
Add missing build dep on google-mock.
- 10. By Thomas Voß
-
More tests passing.
- 9. By Thomas Voß
-
More refactoring of local spike.
- 8. By Thomas Voß
-
Add first wave of acceptance tests and ensure that they are passing.
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-08-14 18:05:23 +0000 |
3 | +++ CMakeLists.txt 2013-11-11 13:09:24 +0000 |
4 | @@ -20,7 +20,7 @@ |
5 | include(GNUInstallDirs) |
6 | |
7 | find_package(PkgConfig) |
8 | -find_package(Boost 1.49 COMPONENTS system program_options) |
9 | +find_package(Boost COMPONENTS filesystem system program_options REQUIRED) |
10 | find_package(GLog) |
11 | pkg_check_modules(DBUS dbus-1 REQUIRED) |
12 | pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) |
13 | @@ -57,6 +57,7 @@ |
14 | add_subdirectory(include) |
15 | add_subdirectory(doc) |
16 | add_subdirectory(src) |
17 | +add_subdirectory(tests) |
18 | |
19 | # There's no nice way to format this. Thanks CMake. |
20 | add_test(LGPL-required |
21 | |
22 | === modified file 'debian/control' |
23 | --- debian/control 2013-08-23 09:51:12 +0000 |
24 | +++ debian/control 2013-11-11 13:09:24 +0000 |
25 | @@ -7,9 +7,18 @@ |
26 | dbus-test-runner, |
27 | debhelper (>= 9), |
28 | doxygen, |
29 | + google-mock, |
30 | + graphviz, |
31 | + gstreamer1.0-plugins-good, |
32 | + gstreamer1.0-fluendo-mp3, |
33 | libboost-dev (>=1.53), |
34 | + libboost-filesystem-dev (>=1.53), |
35 | + libboost-program-options-dev (>=1.53), |
36 | + libboost-system-dev (>=1.53), |
37 | libdbus-1-dev, |
38 | libgoogle-glog-dev, |
39 | + gstreamer1.0-libav, |
40 | + libgstreamer1.0-dev, |
41 | pkg-config, |
42 | Standards-Version: 3.9.4 |
43 | Homepage: https://launchpad.net/music-hub |
44 | |
45 | === modified file 'doc/Doxyfile.in' |
46 | --- doc/Doxyfile.in 2013-08-14 18:05:23 +0000 |
47 | +++ doc/Doxyfile.in 2013-11-11 13:09:24 +0000 |
48 | @@ -668,7 +668,7 @@ |
49 | # directories like "/usr/src/myproject". Separate the files or directories |
50 | # with spaces. |
51 | |
52 | -INPUT = @CMAKE_CURRENT_SOURCE_DIR@ @CMAKE_CURRENT_SOURCE_DIR@/../include |
53 | +INPUT = @CMAKE_CURRENT_SOURCE_DIR@/../include @CMAKE_CURRENT_SOURCE_DIR@/../src |
54 | |
55 | # This tag can be used to specify the character encoding of the source files |
56 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is |
57 | |
58 | === modified file 'include/com/ubuntu/music/connection.h' |
59 | --- include/com/ubuntu/music/connection.h 2013-08-13 14:07:37 +0000 |
60 | +++ include/com/ubuntu/music/connection.h 2013-11-11 13:09:24 +0000 |
61 | @@ -29,21 +29,17 @@ |
62 | { |
63 | class Connection |
64 | { |
65 | - private: |
66 | - struct Private; |
67 | + public: |
68 | + typedef std::function<void()> Disconnector; |
69 | |
70 | - public: |
71 | - Connection(const std::shared_ptr<Private>& d); |
72 | - Connection(const Connection& rhs); |
73 | + Connection(const Disconnector& disconnector); |
74 | ~Connection(); |
75 | |
76 | - Connection& operator=(const Connection& rhs); |
77 | - bool operator==(const Connection& rhs) const; |
78 | - |
79 | bool is_connected() const; |
80 | void disconnect(); |
81 | |
82 | private: |
83 | + struct Private; |
84 | std::shared_ptr<Private> d; |
85 | }; |
86 | |
87 | |
88 | === modified file 'include/com/ubuntu/music/player.h' |
89 | --- include/com/ubuntu/music/player.h 2013-09-08 11:42:36 +0000 |
90 | +++ include/com/ubuntu/music/player.h 2013-11-11 13:09:24 +0000 |
91 | @@ -18,8 +18,7 @@ |
92 | #ifndef COM_UBUNTU_MUSIC_PLAYER_H_ |
93 | #define COM_UBUNTU_MUSIC_PLAYER_H_ |
94 | |
95 | -#include "com/ubuntu/music/connection.h" |
96 | -#include "com/ubuntu/music/track.h" |
97 | +#include <com/ubuntu/music/track.h> |
98 | |
99 | #include <chrono> |
100 | #include <memory> |
101 | @@ -30,17 +29,30 @@ |
102 | { |
103 | namespace music |
104 | { |
105 | +template<typename T> class Property; |
106 | class Service; |
107 | +template<typename T> class Signal; |
108 | class TrackList; |
109 | |
110 | -class Player |
111 | +class Player : public std::enable_shared_from_this<Player> |
112 | { |
113 | public: |
114 | typedef double PlaybackRate; |
115 | typedef double Volume; |
116 | |
117 | + struct Configuration; |
118 | + |
119 | + struct Client |
120 | + { |
121 | + Client() = delete; |
122 | + |
123 | + static const Configuration& default_configuration(); |
124 | + }; |
125 | + |
126 | enum PlaybackStatus |
127 | { |
128 | + null, |
129 | + ready, |
130 | playing, |
131 | paused, |
132 | stopped |
133 | @@ -54,62 +66,45 @@ |
134 | }; |
135 | |
136 | Player(const Player&) = delete; |
137 | - ~Player(); |
138 | + virtual ~Player(); |
139 | |
140 | Player& operator=(const Player&) = delete; |
141 | bool operator==(const Player&) const = delete; |
142 | |
143 | - const std::shared_ptr<TrackList>& track_list() const; |
144 | - |
145 | - bool can_go_next(); |
146 | - void next(); |
147 | - |
148 | - bool can_go_previous(); |
149 | - void previous(); |
150 | - |
151 | - bool can_play(); |
152 | - void play(); |
153 | - |
154 | - bool can_pause(); |
155 | - void pause(); |
156 | - |
157 | - bool can_seek(); |
158 | - void seek_to(const std::chrono::microseconds& offset); |
159 | - |
160 | - void stop(); |
161 | - |
162 | - PlaybackStatus playback_status() const; |
163 | - Connection on_playback_status_changed(const std::function<void(PlaybackStatus)>& handler); |
164 | - |
165 | - LoopStatus loop_status() const; |
166 | - void set_loop_status(LoopStatus new_status); |
167 | - Connection on_loop_status_changed(const std::function<void(LoopStatus)>& handler); |
168 | - |
169 | - PlaybackRate playback_rate() const; |
170 | - void set_playback_rate(PlaybackRate rate); |
171 | - Connection on_playback_rate_changed(const std::function<void(PlaybackRate)>& handler); |
172 | - |
173 | - bool is_shuffle() const; |
174 | - void set_shuffle(bool b); |
175 | - Connection on_shuffle_changed(const std::function<void(bool)>& handler); |
176 | - |
177 | - Track::MetaData meta_data_for_current_track() const; |
178 | - Connection on_meta_data_for_current_track_changed(const std::function<void(const Track::MetaData&)>& handler); |
179 | - |
180 | - Volume volume() const; |
181 | - void set_volume(Volume new_volume); |
182 | - Connection on_volume_changed(const std::function<void(Volume)>& handler); |
183 | - |
184 | - PlaybackRate minimum_playback_rate() const; |
185 | - PlaybackRate maximum_playback_rate() const; |
186 | - |
187 | - private: |
188 | - friend class Service; |
189 | - |
190 | - Player(const std::shared_ptr<Service>& parent); |
191 | - |
192 | - struct Private; |
193 | - std::unique_ptr<Private> d; |
194 | + virtual std::shared_ptr<TrackList> track_list() = 0; |
195 | + |
196 | + virtual bool open_uri(const Track::UriType& uri) = 0; |
197 | + virtual void next() = 0; |
198 | + virtual void previous() = 0; |
199 | + virtual void play() = 0; |
200 | + virtual void pause() = 0; |
201 | + virtual void stop() = 0; |
202 | + virtual void seek_to(const std::chrono::microseconds& offset) = 0; |
203 | + |
204 | + virtual const Property<bool>& can_play() const = 0; |
205 | + virtual const Property<bool>& can_pause() const = 0; |
206 | + virtual const Property<bool>& can_seek() const = 0; |
207 | + virtual const Property<bool>& can_go_previous() const = 0; |
208 | + virtual const Property<bool>& can_go_next() const = 0; |
209 | + virtual const Property<PlaybackStatus>& playback_status() const = 0; |
210 | + virtual const Property<LoopStatus>& loop_status() const = 0; |
211 | + virtual const Property<PlaybackRate>& playback_rate() const = 0; |
212 | + virtual const Property<bool>& is_shuffle() const = 0; |
213 | + virtual const Property<Track::MetaData>& meta_data_for_current_track() const = 0; |
214 | + virtual const Property<Volume>& volume() const = 0; |
215 | + virtual const Property<PlaybackRate>& minimum_playback_rate() const = 0; |
216 | + virtual const Property<PlaybackRate>& maximum_playback_rate() const = 0; |
217 | + |
218 | + virtual Property<LoopStatus>& loop_status() = 0; |
219 | + virtual Property<PlaybackRate>& playback_rate() = 0; |
220 | + virtual Property<bool>& is_shuffle() = 0; |
221 | + virtual Property<Volume>& volume() = 0; |
222 | + |
223 | + virtual const Signal<uint64_t>& seeked_to() const = 0; |
224 | + |
225 | + protected: |
226 | + Player(); |
227 | + |
228 | }; |
229 | } |
230 | } |
231 | |
232 | === added file 'include/com/ubuntu/music/property.h' |
233 | --- include/com/ubuntu/music/property.h 1970-01-01 00:00:00 +0000 |
234 | +++ include/com/ubuntu/music/property.h 2013-11-11 13:09:24 +0000 |
235 | @@ -0,0 +1,140 @@ |
236 | +/* |
237 | + * Copyright © 2013 Canonical Ltd. |
238 | + * |
239 | + * This program is free software: you can redistribute it and/or modify it |
240 | + * under the terms of the GNU Lesser General Public License version 3, |
241 | + * as published by the Free Software Foundation. |
242 | + * |
243 | + * This program is distributed in the hope that it will be useful, |
244 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
245 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
246 | + * GNU Lesser General Public License for more details. |
247 | + * |
248 | + * You should have received a copy of the GNU Lesser General Public License |
249 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
250 | + * |
251 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
252 | + */ |
253 | +#ifndef COM_UBUNTU_MUSIC_PROPERTY_H_ |
254 | +#define COM_UBUNTU_MUSIC_PROPERTY_H_ |
255 | + |
256 | +#include <com/ubuntu/music/signal.h> |
257 | + |
258 | +#include <iostream> |
259 | + |
260 | +namespace com |
261 | +{ |
262 | +namespace ubuntu |
263 | +{ |
264 | +namespace music |
265 | +{ |
266 | +template<typename T> |
267 | +class Property |
268 | +{ |
269 | + private: |
270 | + inline static T& mutable_default_value() |
271 | + { |
272 | + static T default_value = T{}; |
273 | + return default_value; |
274 | + } |
275 | + |
276 | + public: |
277 | + typedef T ValueType; |
278 | + |
279 | + inline static const T& default_value() |
280 | + { |
281 | + return mutable_default_value(); |
282 | + } |
283 | + |
284 | + inline static void set_default_value(const T& new_default_value) |
285 | + { |
286 | + mutable_default_value() = new_default_value; |
287 | + } |
288 | + |
289 | + inline explicit Property(const T& t = Property<T>::default_value()) : value{t} |
290 | + { |
291 | + } |
292 | + |
293 | + inline Property(const Property<T>& rhs) : value{rhs.value} |
294 | + { |
295 | + } |
296 | + |
297 | + inline virtual ~Property() = default; |
298 | + |
299 | + inline Property& operator=(const T& rhs) |
300 | + { |
301 | + set(rhs); |
302 | + return *this; |
303 | + } |
304 | + |
305 | + inline Property& operator=(const Property<T>& rhs) |
306 | + { |
307 | + set(rhs.value); |
308 | + return *this; |
309 | + } |
310 | + |
311 | + inline operator const T&() const |
312 | + { |
313 | + return get(); |
314 | + } |
315 | + |
316 | + inline const T* operator->() const |
317 | + { |
318 | + return &get(); |
319 | + } |
320 | + |
321 | + friend inline bool operator==(const Property<T>& lhs, const T& rhs) |
322 | + { |
323 | + return lhs.get() == rhs.get(); |
324 | + } |
325 | + |
326 | + friend inline bool operator==(const Property<T>& lhs, const Property<T>& rhs) |
327 | + { |
328 | + return lhs.get() == rhs.get(); |
329 | + } |
330 | + |
331 | + inline virtual void set(const T& new_value) |
332 | + { |
333 | + if (value != new_value) |
334 | + { |
335 | + value = new_value; |
336 | + signal_changed(value); |
337 | + } |
338 | + } |
339 | + |
340 | + inline virtual const T& get() const |
341 | + { |
342 | + return value; |
343 | + } |
344 | + |
345 | + inline const Signal<T>& changed() const |
346 | + { |
347 | + return signal_changed; |
348 | + } |
349 | + |
350 | + inline virtual bool update(const std::function<bool(T& t)>& update_functor) |
351 | + { |
352 | + if (update_functor(mutable_get())) |
353 | + { |
354 | + set(value); signal_changed(value); |
355 | + return true; |
356 | + } |
357 | + |
358 | + return false; |
359 | + } |
360 | + |
361 | + protected: |
362 | + inline T& mutable_get() const |
363 | + { |
364 | + return value; |
365 | + } |
366 | + |
367 | + private: |
368 | + mutable T value; |
369 | + Signal<T> signal_changed; |
370 | +}; |
371 | +} |
372 | +} |
373 | +} |
374 | + |
375 | +#endif // COM_UBUNTU_MUSIC_PROPERTY_H_ |
376 | |
377 | === modified file 'include/com/ubuntu/music/service.h' |
378 | --- include/com/ubuntu/music/service.h 2013-08-13 14:07:37 +0000 |
379 | +++ include/com/ubuntu/music/service.h 2013-11-11 13:09:24 +0000 |
380 | @@ -18,6 +18,8 @@ |
381 | #ifndef COM_UBUNTU_MUSIC_SERVICE_H_ |
382 | #define COM_UBUNTU_MUSIC_SERVICE_H_ |
383 | |
384 | +#include <com/ubuntu/music/player.h> |
385 | + |
386 | #include <memory> |
387 | |
388 | namespace com |
389 | @@ -35,16 +37,15 @@ |
390 | }; |
391 | |
392 | Service(const Service&) = delete; |
393 | - ~Service(); |
394 | + virtual ~Service() = default; |
395 | |
396 | Service& operator=(const Service&) = delete; |
397 | bool operator==(const Service&) const = delete; |
398 | |
399 | - std::shared_ptr<Player> create_session(); |
400 | - |
401 | - private: |
402 | - friend struct Client; |
403 | - Service(); |
404 | + virtual std::shared_ptr<Player> create_session(const Player::Configuration&) = 0; |
405 | + |
406 | + protected: |
407 | + Service() = default; |
408 | }; |
409 | } |
410 | } |
411 | |
412 | === added file 'include/com/ubuntu/music/signal.h' |
413 | --- include/com/ubuntu/music/signal.h 1970-01-01 00:00:00 +0000 |
414 | +++ include/com/ubuntu/music/signal.h 2013-11-11 13:09:24 +0000 |
415 | @@ -0,0 +1,149 @@ |
416 | +/* |
417 | + * Copyright © 2013 Canonical Ltd. |
418 | + * |
419 | + * This program is free software: you can redistribute it and/or modify it |
420 | + * under the terms of the GNU Lesser General Public License version 3, |
421 | + * as published by the Free Software Foundation. |
422 | + * |
423 | + * This program is distributed in the hope that it will be useful, |
424 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
425 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
426 | + * GNU Lesser General Public License for more details. |
427 | + * |
428 | + * You should have received a copy of the GNU Lesser General Public License |
429 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
430 | + * |
431 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
432 | + */ |
433 | +#ifndef COM_UBUNTU_MUSIC_SIGNAL_H_ |
434 | +#define COM_UBUNTU_MUSIC_SIGNAL_H_ |
435 | + |
436 | +#include <com/ubuntu/music/connection.h> |
437 | + |
438 | +#include <functional> |
439 | +#include <iostream> |
440 | +#include <list> |
441 | +#include <mutex> |
442 | +#include <set> |
443 | + |
444 | +namespace com |
445 | +{ |
446 | +namespace ubuntu |
447 | +{ |
448 | +namespace music |
449 | +{ |
450 | +template<typename T> |
451 | +class Signal |
452 | +{ |
453 | + public: |
454 | + static unsigned int& tag() |
455 | + { |
456 | + static unsigned int counter = 0; |
457 | + return counter; |
458 | + } |
459 | + |
460 | + typedef std::function<void(const T&)> Slot; |
461 | + |
462 | + inline Signal() : d(new Private()) |
463 | + { |
464 | + } |
465 | + |
466 | + Signal(const Signal&) = delete; |
467 | + inline ~Signal() = default; |
468 | + |
469 | + Signal& operator=(const Signal&) = delete; |
470 | + bool operator==(const Signal&) const = delete; |
471 | + |
472 | + inline Connection connect(const Slot& slot) const |
473 | + { |
474 | + std::lock_guard<std::mutex> lg(d->guard); |
475 | + auto result = d->slots.insert(d->slots.end(), slot); |
476 | + |
477 | + return Connection( |
478 | + std::bind( |
479 | + &Private::disconnect_slot_for_iterator, |
480 | + d, |
481 | + result)); |
482 | + } |
483 | + |
484 | + void operator()(const T& value) |
485 | + { |
486 | + std::lock_guard<std::mutex> lg(d->guard); |
487 | + for(auto slot : d->slots) |
488 | + { |
489 | + slot(value); |
490 | + } |
491 | + } |
492 | + |
493 | + private: |
494 | + struct Private |
495 | + { |
496 | + void disconnect_slot_for_iterator(typename std::list<Slot>::iterator it) |
497 | + { |
498 | + std::lock_guard<std::mutex> lg(guard); |
499 | + slots.erase(it); |
500 | + } |
501 | + |
502 | + std::mutex guard; |
503 | + std::list<Slot> slots; |
504 | + unsigned int counter = Signal<T>::tag()++; |
505 | + }; |
506 | + std::shared_ptr<Private> d; |
507 | +}; |
508 | + |
509 | +template<> |
510 | +class Signal<void> |
511 | +{ |
512 | + public: |
513 | + typedef std::function<void()> Slot; |
514 | + |
515 | + inline Signal() : d(new Private()) |
516 | + { |
517 | + } |
518 | + |
519 | + Signal(const Signal&) = delete; |
520 | + inline ~Signal() = default; |
521 | + |
522 | + Signal& operator=(const Signal&) = delete; |
523 | + bool operator==(const Signal&) const = delete; |
524 | + |
525 | + inline Connection connect(const Slot& slot) const |
526 | + { |
527 | + std::lock_guard<std::mutex> lg(d->guard); |
528 | + auto result = d->slots.insert(d->slots.end(), slot); |
529 | + |
530 | + return Connection( |
531 | + std::bind( |
532 | + &Private::disconnect_slot_for_iterator, |
533 | + d, |
534 | + result)); |
535 | + } |
536 | + |
537 | + void operator()() |
538 | + { |
539 | + std::lock_guard<std::mutex> lg(d->guard); |
540 | + for(auto slot : d->slots) |
541 | + { |
542 | + slot(); |
543 | + } |
544 | + } |
545 | + |
546 | + private: |
547 | + struct Private |
548 | + { |
549 | + void disconnect_slot_for_iterator(typename std::list<Slot>::iterator it) |
550 | + { |
551 | + std::lock_guard<std::mutex> lg(guard); |
552 | + slots.erase(it); |
553 | + } |
554 | + |
555 | + std::mutex guard; |
556 | + std::list<Slot> slots; |
557 | + }; |
558 | + std::shared_ptr<Private> d; |
559 | +}; |
560 | +} |
561 | +} |
562 | +} |
563 | + |
564 | +#endif // COM_UBUNTU_MUSIC_SIGNAL_H_ |
565 | |
566 | === modified file 'include/com/ubuntu/music/track.h' |
567 | --- include/com/ubuntu/music/track.h 2013-08-13 14:07:37 +0000 |
568 | +++ include/com/ubuntu/music/track.h 2013-11-11 13:09:24 +0000 |
569 | @@ -20,9 +20,13 @@ |
570 | |
571 | #include "com/ubuntu/music/connection.h" |
572 | |
573 | +#include <chrono> |
574 | #include <functional> |
575 | +#include <map> |
576 | #include <memory> |
577 | +#include <sstream> |
578 | #include <string> |
579 | +#include <vector> |
580 | |
581 | namespace com |
582 | { |
583 | @@ -30,53 +34,127 @@ |
584 | { |
585 | namespace music |
586 | { |
587 | +template<typename T> class Property; |
588 | + |
589 | class Track |
590 | { |
591 | public: |
592 | typedef std::string UriType; |
593 | + typedef std::string Id; |
594 | |
595 | class MetaData |
596 | { |
597 | - public: |
598 | - typedef std::string KeyType; |
599 | - typedef std::string ValueType; |
600 | - |
601 | - static const KeyType& track_id_key(); |
602 | - |
603 | - ~MetaData(); |
604 | - MetaData(const MetaData&); |
605 | - MetaData& operator=(const MetaData&); |
606 | - bool operator==(const MetaData&) const; |
607 | - |
608 | - bool has_value_for_key(const KeyType& key) const; |
609 | - const ValueType& value_for_key(const KeyType& key) const; |
610 | - |
611 | - void for_each(const std::function<void(const KeyType&, const ValueType&)>& f); |
612 | - |
613 | - private: |
614 | - friend class Player; |
615 | - friend class Track; |
616 | - |
617 | - MetaData(); |
618 | - |
619 | - struct Private; |
620 | - std::unique_ptr<Private> d; |
621 | + public: |
622 | + bool operator==(const MetaData& rhs) const |
623 | + { |
624 | + return map == rhs.map; |
625 | + } |
626 | + |
627 | + bool operator!=(const MetaData& rhs) const |
628 | + { |
629 | + return map != rhs.map; |
630 | + } |
631 | + |
632 | + template<typename Tag> |
633 | + std::size_t count() const |
634 | + { |
635 | + return count(Tag::name()); |
636 | + } |
637 | + |
638 | + template<typename Tag> |
639 | + void set(const typename Tag::ValueType& value) |
640 | + { |
641 | + std::stringstream ss; ss << value; |
642 | + set(Tag::name(), ss.str()); |
643 | + } |
644 | + |
645 | + template<typename Tag> |
646 | + typename Tag::ValueType get() const |
647 | + { |
648 | + std::stringstream ss(get(Tag::name())); |
649 | + typename Tag::ValueType value; ss >> value; |
650 | + |
651 | + return std::move(value); |
652 | + } |
653 | + |
654 | + std::size_t count(const std::string& key) const |
655 | + { |
656 | + return map.count(key); |
657 | + } |
658 | + |
659 | + void set(const std::string& key, const std::string& value) |
660 | + { |
661 | + map[key] = value; |
662 | + } |
663 | + |
664 | + const std::string& get(const std::string& key) const |
665 | + { |
666 | + return map.at(key); |
667 | + } |
668 | + |
669 | + const std::map<std::string, std::string>& operator*() const |
670 | + { |
671 | + return map; |
672 | + } |
673 | + |
674 | + private: |
675 | + std::map<std::string, std::string> map; |
676 | }; |
677 | |
678 | - Track(const Track&); |
679 | - ~Track(); |
680 | + Track(const Id& id); |
681 | + Track(const Track&) = delete; |
682 | + virtual ~Track(); |
683 | |
684 | Track& operator=(const Track&); |
685 | bool operator==(const Track&) const; |
686 | |
687 | - const UriType& uri() const; |
688 | - |
689 | - const MetaData& meta_data() const; |
690 | - Connection on_meta_data_changed(const std::function<void(const MetaData&)>& f); |
691 | - |
692 | - private: |
693 | - explicit Track(const UriType& uri, const MetaData& meta_data); |
694 | - |
695 | + virtual const Id& id() const; |
696 | + /* |
697 | + class MetaData |
698 | + { |
699 | + public: |
700 | + MetaData() = default; |
701 | + MetaData(const MetaData&) = default; |
702 | + ~MetaData() = default; |
703 | + |
704 | + MetaData& operator=(const MetaData&) = default; |
705 | + |
706 | + bool operator==(const MetaData&) const |
707 | + { |
708 | + return true; |
709 | + } |
710 | + |
711 | + bool operator!=(const MetaData&) const |
712 | + { |
713 | + return false; |
714 | + } |
715 | + |
716 | + struct NotImplementedFields |
717 | + { |
718 | + NotImplementedFields() = default; |
719 | + |
720 | + virtual const UriType& uri() const = 0; |
721 | + virtual const std::chrono::microseconds length() const = 0; |
722 | + virtual const UriType& art_uri() const = 0; |
723 | + virtual const std::string& album() const = 0; |
724 | + virtual const std::vector<std::string>& album_artist() const = 0; |
725 | + virtual const std::vector<std::string>& artist() const = 0; |
726 | + virtual const std::string& as_text() const = 0; |
727 | + virtual unsigned int audio_bpm() const = 0; |
728 | + virtual float auto_rating() const = 0; |
729 | + virtual const std::vector<std::string>& comment() const = 0; |
730 | + virtual const std::vector<std::string>& composer() const = 0; |
731 | + virtual unsigned int disc_number() const = 0; |
732 | + virtual const std::vector<std::string>& genre() const = 0; |
733 | + virtual const std::vector<std::string>& lyricist() const = 0; |
734 | + virtual const std::string title() const = 0; |
735 | + virtual unsigned int track_number() const = 0; |
736 | + virtual unsigned int use_count() const = 0; |
737 | + virtual float user_rating() const = 0; |
738 | + }; |
739 | + }; |
740 | +*/ |
741 | +private: |
742 | struct Private; |
743 | std::unique_ptr<Private> d; |
744 | }; |
745 | |
746 | === modified file 'include/com/ubuntu/music/track_list.h' |
747 | --- include/com/ubuntu/music/track_list.h 2013-08-13 14:07:37 +0000 |
748 | +++ include/com/ubuntu/music/track_list.h 2013-11-11 13:09:24 +0000 |
749 | @@ -18,9 +18,10 @@ |
750 | #ifndef COM_UBUNTU_MUSIC_TRACK_LIST_H_ |
751 | #define COM_UBUNTU_MUSIC_TRACK_LIST_H_ |
752 | |
753 | -#include "com/ubuntu/music/track.h" |
754 | +#include <com/ubuntu/music/track.h> |
755 | |
756 | #include <functional> |
757 | +#include <list> |
758 | #include <memory> |
759 | |
760 | namespace com |
761 | @@ -29,33 +30,41 @@ |
762 | { |
763 | namespace music |
764 | { |
765 | -class TrackList |
766 | +class Player; |
767 | +template<typename T> class Property; |
768 | +template<typename T> class Signal; |
769 | + |
770 | +class TrackList : public std::enable_shared_from_this<TrackList> |
771 | { |
772 | public: |
773 | - TrackList(); |
774 | - TrackList(const TrackList& rhs); |
775 | + typedef std::list<Track::Id> Container; |
776 | + typedef Container::iterator Iterator; |
777 | + typedef Container::const_iterator ConstIterator; |
778 | + |
779 | + static const Track::Id& after_empty_track(); |
780 | + |
781 | + TrackList(const TrackList&) = delete; |
782 | ~TrackList(); |
783 | |
784 | - TrackList& operator=(const TrackList&); |
785 | - bool operator==(const TrackList&) const; |
786 | - |
787 | - bool is_editable(); |
788 | - |
789 | - void add_track_with_uri(const Track::UriType& uri, const Track& after, bool make_current); |
790 | - void remove_track(const Track& track); |
791 | - |
792 | - void for_each(const std::function<void(const Track&)> functor) const; |
793 | - |
794 | - void go_to(const Track& track); |
795 | - |
796 | - Connection on_track_list_replaced(const std::function<void()>& slot); |
797 | - Connection on_track_added(const std::function<void(const Track& t)>& slot); |
798 | - Connection on_track_removed(const std::function<void(const Track& t)>& slot); |
799 | - Connection on_current_track_changed(const std::function<void(const Track&)>& slot); |
800 | + TrackList& operator=(const TrackList&) = delete; |
801 | + bool operator==(const TrackList&) const = delete; |
802 | + |
803 | + virtual const Property<bool>& can_edit_tracks() const = 0; |
804 | + virtual const Property<Container>& tracks() const = 0; |
805 | + |
806 | + virtual Track::MetaData query_meta_data_for_track(const Track::Id& id) = 0; |
807 | + virtual void add_track_with_uri_at(const Track::UriType& uri, const Track::Id& position, bool make_current) = 0; |
808 | + virtual void remove_track(const Track::Id& id) = 0; |
809 | + |
810 | + virtual void go_to(const Track::Id& track) = 0; |
811 | + |
812 | + virtual const Signal<void>& on_track_list_replaced() const = 0; |
813 | + virtual const Signal<Track::Id>& on_track_added() const = 0; |
814 | + virtual const Signal<Track::Id>& on_track_removed() const = 0; |
815 | + virtual const Signal<Track::Id>& on_track_changed() const = 0; |
816 | |
817 | - private: |
818 | - struct Private; |
819 | - std::unique_ptr<Private> d; |
820 | +protected: |
821 | + TrackList(); |
822 | }; |
823 | } |
824 | } |
825 | |
826 | === modified file 'src/com/ubuntu/music/CMakeLists.txt' |
827 | --- src/com/ubuntu/music/CMakeLists.txt 2013-08-14 20:10:09 +0000 |
828 | +++ src/com/ubuntu/music/CMakeLists.txt 2013-11-11 13:09:24 +0000 |
829 | @@ -1,15 +1,36 @@ |
830 | -add_library( |
831 | - music_hub SHARED |
832 | +pkg_check_modules(PC_GSTREAMER_1_0 REQUIRED gstreamer-1.0) |
833 | + |
834 | +include_directories(${PC_GSTREAMER_1_0_INCLUDE_DIRS}) |
835 | + |
836 | +add_library( |
837 | + music-hub-common SHARED |
838 | + |
839 | + the_session_bus.cpp |
840 | +) |
841 | + |
842 | +target_link_libraries( |
843 | + music-hub-common |
844 | + |
845 | + ${Boost_LIBRARIES} |
846 | + ${DBUS_LIBRARIES} |
847 | +) |
848 | + |
849 | +add_library( |
850 | + music-hub-client SHARED |
851 | |
852 | connection.cpp |
853 | player.cpp |
854 | service.cpp |
855 | track.cpp |
856 | track_list.cpp |
857 | + |
858 | + player_stub.cpp |
859 | + service_stub.cpp |
860 | + track_list_stub.cpp |
861 | ) |
862 | |
863 | set_target_properties( |
864 | - music_hub |
865 | + music-hub-client |
866 | |
867 | PROPERTIES |
868 | VERSION ${UBUNTU_MUSIC_HUB_VERSION_MAJOR}.${UBUNTU_MUSIC_HUB_VERSION_MINOR}.${UBUNTU_MUSIC_HUB_VERSION_PATCH} |
869 | @@ -17,13 +38,39 @@ |
870 | ) |
871 | |
872 | target_link_libraries( |
873 | - music_hub |
874 | + music-hub-client |
875 | + |
876 | + music-hub-common |
877 | |
878 | ${DBUS_LIBRARIES} |
879 | ${GLog_LIBRARY} |
880 | ) |
881 | |
882 | install( |
883 | - TARGETS music_hub |
884 | + TARGETS music-hub-client |
885 | DESTINATION ${CMAKE_INSTALL_LIBDIR} |
886 | -) |
887 | \ No newline at end of file |
888 | +) |
889 | + |
890 | +add_library( |
891 | + music-hub-service |
892 | + |
893 | + engine.cpp |
894 | + gstreamer/engine.cpp |
895 | + |
896 | + player_skeleton.cpp |
897 | + player_implementation.cpp |
898 | + service_skeleton.cpp |
899 | + service_implementation.cpp |
900 | + track_list_skeleton.cpp |
901 | + track_list_implementation.cpp |
902 | +) |
903 | + |
904 | +target_link_libraries( |
905 | + music-hub-service |
906 | + |
907 | + music-hub-common |
908 | + |
909 | + ${DBUS_LIBRARIES} |
910 | + ${GLog_LIBRARY} |
911 | + ${PC_GSTREAMER_1_0_LIBRARIES} |
912 | +) |
913 | |
914 | === added file 'src/com/ubuntu/music/codec.h' |
915 | --- src/com/ubuntu/music/codec.h 1970-01-01 00:00:00 +0000 |
916 | +++ src/com/ubuntu/music/codec.h 2013-11-11 13:09:24 +0000 |
917 | @@ -0,0 +1,78 @@ |
918 | +/* |
919 | + * Copyright © 2013 Canonical Ltd. |
920 | + * |
921 | + * This program is free software: you can redistribute it and/or modify it |
922 | + * under the terms of the GNU Lesser General Public License version 3, |
923 | + * as published by the Free Software Foundation. |
924 | + * |
925 | + * This program is distributed in the hope that it will be useful, |
926 | + * but WITHOUT ANY WARRANTY {} without even the implied warranty of |
927 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
928 | + * GNU Lesser General Public License for more details. |
929 | + * |
930 | + * You should have received a copy of the GNU Lesser General Public License |
931 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
932 | + * |
933 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
934 | + */ |
935 | + |
936 | +#ifndef CODEC_H_ |
937 | +#define CODEC_H_ |
938 | + |
939 | +#include <com/ubuntu/music/track.h> |
940 | + |
941 | +#include <org/freedesktop/dbus/codec.h> |
942 | + |
943 | +namespace org |
944 | +{ |
945 | +namespace freedesktop |
946 | +{ |
947 | +namespace dbus |
948 | +{ |
949 | +namespace helper |
950 | +{ |
951 | +template<> |
952 | +struct TypeMapper<com::ubuntu::music::Track::MetaData> |
953 | +{ |
954 | + constexpr static ArgumentType type_value() |
955 | + { |
956 | + return ArgumentType::floating_point; |
957 | + } |
958 | + constexpr static bool is_basic_type() |
959 | + { |
960 | + return false; |
961 | + } |
962 | + constexpr static bool requires_signature() |
963 | + { |
964 | + return false; |
965 | + } |
966 | + |
967 | + static std::string signature() |
968 | + { |
969 | + static const std::string s = TypeMapper<double>::signature(); |
970 | + return s; |
971 | + } |
972 | +}; |
973 | +} |
974 | + |
975 | +template<> |
976 | +struct Codec<com::ubuntu::music::Track::MetaData> |
977 | +{ |
978 | + static void encode_argument(DBusMessageIter* out, const com::ubuntu::music::Track::MetaData& in) |
979 | + { |
980 | + Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::encode_argument(out, in.value()); |
981 | + } |
982 | + |
983 | + static void decode_argument(DBusMessageIter* out, com::ubuntu::location::units::Quantity<T>& in) |
984 | + { |
985 | + typename com::ubuntu::location::units::Quantity<T>::value_type value; |
986 | + Codec<typename com::ubuntu::location::units::Quantity<T>::value_type>::decode_argument(out, value); |
987 | + in = com::ubuntu::location::units::Quantity<T>::from_value(value); |
988 | + dbus_message_iter_next(out); |
989 | + } |
990 | +}; |
991 | +} |
992 | +} |
993 | +} |
994 | + |
995 | +#endif // CODEC_H_ |
996 | |
997 | === modified file 'src/com/ubuntu/music/connection.cpp' |
998 | --- src/com/ubuntu/music/connection.cpp 2013-08-13 14:07:37 +0000 |
999 | +++ src/com/ubuntu/music/connection.cpp 2013-11-11 13:09:24 +0000 |
1000 | @@ -18,18 +18,41 @@ |
1001 | |
1002 | #include "com/ubuntu/music/connection.h" |
1003 | |
1004 | -#include "connection_private.h" |
1005 | - |
1006 | #include <functional> |
1007 | #include <memory> |
1008 | +#include <mutex> |
1009 | |
1010 | namespace music = com::ubuntu::music; |
1011 | |
1012 | -music::Connection::Connection(const std::shared_ptr<music::Connection::Private>& p) : d(p) |
1013 | +struct music::Connection::Private |
1014 | { |
1015 | -} |
1016 | - |
1017 | -music::Connection::Connection(const music::Connection& rhs) : d(rhs.d) |
1018 | + Private(const music::Connection::Disconnector& disconnector) |
1019 | + : disconnector(disconnector) |
1020 | + { |
1021 | + } |
1022 | + |
1023 | + ~Private() |
1024 | + { |
1025 | + } |
1026 | + |
1027 | + void disconnect() |
1028 | + { |
1029 | + static const music::Connection::Disconnector empty_disconnector{}; |
1030 | + |
1031 | + std::lock_guard<std::mutex> lg(guard); |
1032 | + |
1033 | + if (!disconnector) |
1034 | + return; |
1035 | + |
1036 | + disconnector(); |
1037 | + disconnector = empty_disconnector; |
1038 | + } |
1039 | + |
1040 | + std::mutex guard; |
1041 | + music::Connection::Disconnector disconnector; |
1042 | +}; |
1043 | + |
1044 | +music::Connection::Connection(const music::Connection::Disconnector& disconnector) : d(new Private(disconnector)) |
1045 | { |
1046 | } |
1047 | |
1048 | @@ -37,23 +60,12 @@ |
1049 | { |
1050 | } |
1051 | |
1052 | -music::Connection& music::Connection::operator=(const music::Connection& rhs) |
1053 | -{ |
1054 | - d = rhs.d; |
1055 | - return *this; |
1056 | -} |
1057 | - |
1058 | -bool music::Connection::operator==(const music::Connection& rhs) const |
1059 | -{ |
1060 | - return d == rhs.d; |
1061 | -} |
1062 | - |
1063 | bool music::Connection::is_connected() const |
1064 | { |
1065 | - return d->connection.connected(); |
1066 | + return (d->disconnector ? true : false); |
1067 | } |
1068 | |
1069 | void music::Connection::disconnect() |
1070 | { |
1071 | - d->connection.disconnect(); |
1072 | + d->disconnect(); |
1073 | } |
1074 | |
1075 | === added file 'src/com/ubuntu/music/engine.cpp' |
1076 | --- src/com/ubuntu/music/engine.cpp 1970-01-01 00:00:00 +0000 |
1077 | +++ src/com/ubuntu/music/engine.cpp 2013-11-11 13:09:24 +0000 |
1078 | @@ -0,0 +1,163 @@ |
1079 | +/* |
1080 | + * Copyright © 2013 Canonical Ltd. |
1081 | + * |
1082 | + * This program is free software: you can redistribute it and/or modify it |
1083 | + * under the terms of the GNU Lesser General Public License version 3, |
1084 | + * as published by the Free Software Foundation. |
1085 | + * |
1086 | + * This program is distributed in the hope that it will be useful, |
1087 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1088 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1089 | + * GNU Lesser General Public License for more details. |
1090 | + * |
1091 | + * You should have received a copy of the GNU Lesser General Public License |
1092 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1093 | + * |
1094 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1095 | + */ |
1096 | + |
1097 | +#include "engine.h" |
1098 | + |
1099 | +#include <exception> |
1100 | + |
1101 | +namespace music = com::ubuntu::music; |
1102 | + |
1103 | +const std::string& music::Engine::Xesam::album() |
1104 | +{ |
1105 | + static const std::string s{"xesam:album"}; |
1106 | + return s; |
1107 | +} |
1108 | + |
1109 | +const std::string& music::Engine::Xesam::album_artist() |
1110 | +{ |
1111 | + static const std::string s{"xesam:album_artist"}; |
1112 | + return s; |
1113 | +} |
1114 | + |
1115 | +const std::string& music::Engine::Xesam::artist() |
1116 | +{ |
1117 | + static const std::string s{"xesam:artist"}; |
1118 | + return s; |
1119 | +} |
1120 | + |
1121 | +const std::string& music::Engine::Xesam::as_text() |
1122 | +{ |
1123 | + static const std::string s{"xesam:as_text"}; |
1124 | + return s; |
1125 | +} |
1126 | + |
1127 | +const std::string& music::Engine::Xesam::audio_bpm() |
1128 | +{ |
1129 | + static const std::string s{"xesam:audio_bmp"}; |
1130 | + return s; |
1131 | +} |
1132 | + |
1133 | +const std::string& music::Engine::Xesam::auto_rating() |
1134 | +{ |
1135 | + static const std::string s{"xesam:autoRating"}; |
1136 | + return s; |
1137 | +} |
1138 | + |
1139 | +const std::string& music::Engine::Xesam::comment() |
1140 | +{ |
1141 | + static const std::string s{"xesam:comment"}; |
1142 | + return s; |
1143 | +} |
1144 | + |
1145 | +const std::string& music::Engine::Xesam::composer() |
1146 | +{ |
1147 | + static const std::string s{"xesam:composer"}; |
1148 | + return s; |
1149 | +} |
1150 | + |
1151 | +const std::string& music::Engine::Xesam::content_created() |
1152 | +{ |
1153 | + static const std::string s{"xesam:contentCreated"}; |
1154 | + return s; |
1155 | +} |
1156 | + |
1157 | +const std::string& music::Engine::Xesam::disc_number() |
1158 | +{ |
1159 | + static const std::string s{"xesam:discNumber"}; |
1160 | + return s; |
1161 | +} |
1162 | + |
1163 | +const std::string& music::Engine::Xesam::first_used() |
1164 | +{ |
1165 | + static const std::string s{"xesam:firstUsed"}; |
1166 | + return s; |
1167 | +} |
1168 | + |
1169 | +const std::string& music::Engine::Xesam::genre() |
1170 | +{ |
1171 | + static const std::string s{"xesam:genre"}; |
1172 | + return s; |
1173 | +} |
1174 | + |
1175 | +const std::string& music::Engine::Xesam::last_used() |
1176 | +{ |
1177 | + static const std::string s{"xesam:lastUsed"}; |
1178 | + return s; |
1179 | +} |
1180 | + |
1181 | +const std::string& music::Engine::Xesam::lyricist() |
1182 | +{ |
1183 | + static const std::string s{"xesam:lyricist"}; |
1184 | + return s; |
1185 | +} |
1186 | + |
1187 | +const std::string& music::Engine::Xesam::title() |
1188 | +{ |
1189 | + static const std::string s{"xesam:title"}; |
1190 | + return s; |
1191 | +} |
1192 | + |
1193 | +const std::string& music::Engine::Xesam::track_number() |
1194 | +{ |
1195 | + static const std::string s{"xesam:trackNumber"}; |
1196 | + return s; |
1197 | +} |
1198 | + |
1199 | +const std::string& music::Engine::Xesam::url() |
1200 | +{ |
1201 | + static const std::string s{"xesam:url"}; |
1202 | + return s; |
1203 | +} |
1204 | + |
1205 | +const std::string& music::Engine::Xesam::use_count() |
1206 | +{ |
1207 | + static const std::string s{"xesam:useCount"}; |
1208 | + return s; |
1209 | +} |
1210 | + |
1211 | +const std::string& music::Engine::Xesam::user_rating() |
1212 | +{ |
1213 | + static const std::string s{"xesam:userRating"}; |
1214 | + return s; |
1215 | +} |
1216 | + |
1217 | +double music::Engine::Volume::min() |
1218 | +{ |
1219 | + return 0.; |
1220 | +} |
1221 | + |
1222 | +double music::Engine::Volume::max() |
1223 | +{ |
1224 | + return 1.; |
1225 | +} |
1226 | + |
1227 | +music::Engine::Volume::Volume(double v) : value(v) |
1228 | +{ |
1229 | + if (value < min() || value > max()) |
1230 | + throw std::runtime_error("Value exceeds limits"); |
1231 | +} |
1232 | + |
1233 | +bool music::Engine::Volume::operator!=(const music::Engine::Volume& rhs) const |
1234 | +{ |
1235 | + return value != rhs.value; |
1236 | +} |
1237 | + |
1238 | +bool music::Engine::Volume::operator==(const music::Engine::Volume& rhs) const |
1239 | +{ |
1240 | + return value == rhs.value; |
1241 | +} |
1242 | |
1243 | === added file 'src/com/ubuntu/music/engine.h' |
1244 | --- src/com/ubuntu/music/engine.h 1970-01-01 00:00:00 +0000 |
1245 | +++ src/com/ubuntu/music/engine.h 2013-11-11 13:09:24 +0000 |
1246 | @@ -0,0 +1,114 @@ |
1247 | +/* |
1248 | + * Copyright © 2013 Canonical Ltd. |
1249 | + * |
1250 | + * This program is free software: you can redistribute it and/or modify it |
1251 | + * under the terms of the GNU Lesser General Public License version 3, |
1252 | + * as published by the Free Software Foundation. |
1253 | + * |
1254 | + * This program is distributed in the hope that it will be useful, |
1255 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1256 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1257 | + * GNU Lesser General Public License for more details. |
1258 | + * |
1259 | + * You should have received a copy of the GNU Lesser General Public License |
1260 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1261 | + * |
1262 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1263 | + */ |
1264 | +#ifndef COM_UBUNTU_MUSIC_ENGINE_H_ |
1265 | +#define COM_UBUNTU_MUSIC_ENGINE_H_ |
1266 | + |
1267 | +#include <com/ubuntu/music/property.h> |
1268 | +#include <com/ubuntu/music/track.h> |
1269 | + |
1270 | +#include <chrono> |
1271 | + |
1272 | +namespace com |
1273 | +{ |
1274 | +namespace ubuntu |
1275 | +{ |
1276 | +namespace music |
1277 | +{ |
1278 | +class Engine |
1279 | +{ |
1280 | +public: |
1281 | + |
1282 | + enum class State |
1283 | + { |
1284 | + ready, |
1285 | + busy, |
1286 | + playing, |
1287 | + paused, |
1288 | + stopped |
1289 | + }; |
1290 | + |
1291 | + struct Xesam |
1292 | + { |
1293 | + static const std::string& album(); |
1294 | + static const std::string& album_artist(); |
1295 | + static const std::string& artist(); |
1296 | + static const std::string& as_text(); |
1297 | + static const std::string& audio_bpm(); |
1298 | + static const std::string& auto_rating(); |
1299 | + static const std::string& comment(); |
1300 | + static const std::string& composer(); |
1301 | + static const std::string& content_created(); |
1302 | + static const std::string& disc_number(); |
1303 | + static const std::string& first_used(); |
1304 | + static const std::string& genre(); |
1305 | + static const std::string& last_used(); |
1306 | + static const std::string& lyricist(); |
1307 | + static const std::string& title(); |
1308 | + static const std::string& track_number(); |
1309 | + static const std::string& url(); |
1310 | + static const std::string& use_count(); |
1311 | + static const std::string& user_rating(); |
1312 | + }; |
1313 | + |
1314 | + struct Volume |
1315 | + { |
1316 | + static double min(); |
1317 | + static double max(); |
1318 | + |
1319 | + explicit Volume(double v = max()); |
1320 | + |
1321 | + bool operator!=(const Volume& rhs) const; |
1322 | + bool operator==(const Volume& rhs) const; |
1323 | + |
1324 | + double value; |
1325 | + }; |
1326 | + |
1327 | + class MetaDataExtractor |
1328 | + { |
1329 | + public: |
1330 | + virtual Track::MetaData meta_data_for_track_with_uri(const Track::UriType& uri) = 0; |
1331 | + |
1332 | + protected: |
1333 | + MetaDataExtractor() = default; |
1334 | + MetaDataExtractor(const MetaDataExtractor&) = delete; |
1335 | + virtual ~MetaDataExtractor() = default; |
1336 | + |
1337 | + MetaDataExtractor& operator=(const MetaDataExtractor&) = delete; |
1338 | + }; |
1339 | + |
1340 | + virtual const std::shared_ptr<MetaDataExtractor>& meta_data_extractor() const = 0; |
1341 | + |
1342 | + virtual const Property<State>& state() const = 0; |
1343 | + |
1344 | + virtual bool open_resource_for_uri(const Track::UriType& uri) = 0; |
1345 | + |
1346 | + virtual bool play() = 0; |
1347 | + virtual bool stop() = 0; |
1348 | + virtual bool pause() = 0; |
1349 | + virtual bool seek_to(const std::chrono::microseconds& ts) = 0; |
1350 | + |
1351 | + virtual const Property<Volume>& volume() const = 0; |
1352 | + virtual Property<Volume>& volume() = 0; |
1353 | + |
1354 | + virtual const Property<std::tuple<Track::UriType, Track::MetaData>>& track_meta_data() const = 0; |
1355 | +}; |
1356 | +} |
1357 | +} |
1358 | +} |
1359 | + |
1360 | +#endif // COM_UBUNTU_MUSIC_ENGINE_H_ |
1361 | |
1362 | === added directory 'src/com/ubuntu/music/gstreamer' |
1363 | === added file 'src/com/ubuntu/music/gstreamer/bus.h' |
1364 | --- src/com/ubuntu/music/gstreamer/bus.h 1970-01-01 00:00:00 +0000 |
1365 | +++ src/com/ubuntu/music/gstreamer/bus.h 2013-11-11 13:09:24 +0000 |
1366 | @@ -0,0 +1,345 @@ |
1367 | +/* |
1368 | + * Copyright © 2013 Canonical Ltd. |
1369 | + * |
1370 | + * This program is free software: you can redistribute it and/or modify it |
1371 | + * under the terms of the GNU Lesser General Public License version 3, |
1372 | + * as published by the Free Software Foundation. |
1373 | + * |
1374 | + * This program is distributed in the hope that it will be useful, |
1375 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1376 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1377 | + * GNU Lesser General Public License for more details. |
1378 | + * |
1379 | + * You should have received a copy of the GNU Lesser General Public License |
1380 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1381 | + * |
1382 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1383 | + */ |
1384 | + |
1385 | +#ifndef GSTREAMER_BUS_H_ |
1386 | +#define GSTREAMER_BUS_H_ |
1387 | + |
1388 | +#include <com/ubuntu/music/signal.h> |
1389 | + |
1390 | +#include <gst/gst.h> |
1391 | + |
1392 | +#include <boost/flyweight.hpp> |
1393 | + |
1394 | +#include <exception> |
1395 | +#include <functional> |
1396 | +#include <memory> |
1397 | +#include <tuple> |
1398 | + |
1399 | +namespace gstreamer |
1400 | +{ |
1401 | +class Bus |
1402 | +{ |
1403 | +public: |
1404 | + struct Message |
1405 | + { |
1406 | + ~Message() |
1407 | + { |
1408 | + if (cleanup) |
1409 | + cleanup(); |
1410 | + |
1411 | + gst_message_unref(message); |
1412 | + } |
1413 | + |
1414 | + Message(GstMessage* msg) |
1415 | + : message(msg), |
1416 | + type(GST_MESSAGE_TYPE(msg)), |
1417 | + source(GST_MESSAGE_SRC_NAME(msg)), |
1418 | + sequence_number(gst_message_get_seqnum(msg)) |
1419 | + { |
1420 | + switch(type) |
1421 | + { |
1422 | + case GST_MESSAGE_UNKNOWN: |
1423 | + throw std::runtime_error("Cannot construct message for type unknown"); |
1424 | + break; |
1425 | + case GST_MESSAGE_EOS: |
1426 | + break; |
1427 | + case GST_MESSAGE_ERROR: |
1428 | + { |
1429 | + gst_message_parse_error( |
1430 | + msg, |
1431 | + &detail.error_warning_info.error, |
1432 | + &detail.error_warning_info.debug); |
1433 | + cleanup = [this]() |
1434 | + { |
1435 | + g_error_free(detail.error_warning_info.error); |
1436 | + g_free(detail.error_warning_info.debug); |
1437 | + }; |
1438 | + break; |
1439 | + } |
1440 | + case GST_MESSAGE_WARNING: |
1441 | + gst_message_parse_warning( |
1442 | + msg, |
1443 | + &detail.error_warning_info.error, |
1444 | + &detail.error_warning_info.debug); |
1445 | + cleanup = [this]() |
1446 | + { |
1447 | + g_error_free(detail.error_warning_info.error); |
1448 | + g_free(detail.error_warning_info.debug); |
1449 | + }; |
1450 | + break; |
1451 | + break; |
1452 | + case GST_MESSAGE_INFO: |
1453 | + gst_message_parse_info( |
1454 | + msg, |
1455 | + &detail.error_warning_info.error, |
1456 | + &detail.error_warning_info.debug); |
1457 | + cleanup = [this]() |
1458 | + { |
1459 | + g_error_free(detail.error_warning_info.error); |
1460 | + g_free(detail.error_warning_info.debug); |
1461 | + }; |
1462 | + break; |
1463 | + break; |
1464 | + case GST_MESSAGE_TAG: |
1465 | + gst_message_parse_tag( |
1466 | + msg, |
1467 | + &detail.tag.tag_list); |
1468 | + cleanup = [this]() |
1469 | + { |
1470 | + gst_tag_list_free(detail.tag.tag_list); |
1471 | + }; |
1472 | + break; |
1473 | + case GST_MESSAGE_BUFFERING: |
1474 | + gst_message_parse_buffering( |
1475 | + msg, |
1476 | + &detail.buffering.percent); |
1477 | + break; |
1478 | + case GST_MESSAGE_STATE_CHANGED: |
1479 | + gst_message_parse_state_changed( |
1480 | + msg, |
1481 | + &detail.state_changed.old_state, |
1482 | + &detail.state_changed.new_state, |
1483 | + &detail.state_changed.pending_state); |
1484 | + break; |
1485 | + case GST_MESSAGE_STATE_DIRTY: |
1486 | + break; |
1487 | + case GST_MESSAGE_STEP_DONE: |
1488 | + gst_message_parse_step_done( |
1489 | + msg, |
1490 | + &detail.step_done.format, |
1491 | + &detail.step_done.amount, |
1492 | + &detail.step_done.rate, |
1493 | + &detail.step_done.flush, |
1494 | + &detail.step_done.intermediate, |
1495 | + &detail.step_done.duration, |
1496 | + &detail.step_done.eos |
1497 | + ); |
1498 | + break; |
1499 | + case GST_MESSAGE_CLOCK_PROVIDE: |
1500 | + gst_message_parse_clock_provide( |
1501 | + msg, |
1502 | + &detail.clock_provide.clock, |
1503 | + &detail.clock_provide.ready); |
1504 | + break; |
1505 | + case GST_MESSAGE_CLOCK_LOST: |
1506 | + gst_message_parse_clock_lost( |
1507 | + msg, |
1508 | + &detail.clock_lost.clock); |
1509 | + break; |
1510 | + case GST_MESSAGE_NEW_CLOCK: |
1511 | + gst_message_parse_new_clock( |
1512 | + msg, |
1513 | + &detail.clock_new.clock); |
1514 | + break; |
1515 | + case GST_MESSAGE_STRUCTURE_CHANGE: |
1516 | + break; |
1517 | + case GST_MESSAGE_STREAM_STATUS: |
1518 | + break; |
1519 | + case GST_MESSAGE_APPLICATION: |
1520 | + break; |
1521 | + case GST_MESSAGE_ELEMENT: |
1522 | + break; |
1523 | + case GST_MESSAGE_SEGMENT_START: |
1524 | + gst_message_parse_segment_start( |
1525 | + msg, |
1526 | + &detail.segment_start.format, |
1527 | + &detail.segment_start.position); |
1528 | + break; |
1529 | + case GST_MESSAGE_SEGMENT_DONE: |
1530 | + gst_message_parse_segment_done( |
1531 | + msg, |
1532 | + &detail.segment_done.format, |
1533 | + &detail.segment_done.position); |
1534 | + break; |
1535 | + case GST_MESSAGE_DURATION_CHANGED: |
1536 | + break; |
1537 | + case GST_MESSAGE_LATENCY: |
1538 | + break; |
1539 | + case GST_MESSAGE_ASYNC_START: |
1540 | + break; |
1541 | + case GST_MESSAGE_ASYNC_DONE: |
1542 | + gst_message_parse_async_done( |
1543 | + msg, |
1544 | + &detail.async_done.running_time); |
1545 | + break; |
1546 | + case GST_MESSAGE_REQUEST_STATE: |
1547 | + break; |
1548 | + case GST_MESSAGE_STEP_START: |
1549 | + gst_message_parse_step_start( |
1550 | + msg, |
1551 | + &detail.step_start.active, |
1552 | + &detail.step_start.format, |
1553 | + &detail.step_start.amount, |
1554 | + &detail.step_start.rate, |
1555 | + &detail.step_start.flush, |
1556 | + &detail.step_start.intermediate); |
1557 | + break; |
1558 | + case GST_MESSAGE_QOS: |
1559 | + gst_message_parse_qos( |
1560 | + msg, |
1561 | + &detail.qos.live, |
1562 | + &detail.qos.running_time, |
1563 | + &detail.qos.stream_time, |
1564 | + &detail.qos.timestamp, |
1565 | + &detail.qos.duration); |
1566 | + break; |
1567 | + case GST_MESSAGE_PROGRESS: |
1568 | + break; |
1569 | + case GST_MESSAGE_TOC: |
1570 | + break; |
1571 | + case GST_MESSAGE_RESET_TIME: |
1572 | + break; |
1573 | + case GST_MESSAGE_STREAM_START: |
1574 | + break; |
1575 | + case GST_MESSAGE_NEED_CONTEXT: |
1576 | + break; |
1577 | + case GST_MESSAGE_HAVE_CONTEXT: |
1578 | + break; |
1579 | + case GST_MESSAGE_ANY: |
1580 | + break; |
1581 | + } |
1582 | + } |
1583 | + |
1584 | + GstMessage* message; |
1585 | + GstMessageType type; |
1586 | + boost::flyweight<std::string> source; |
1587 | + uint32_t sequence_number; |
1588 | + |
1589 | + union Detail |
1590 | + { |
1591 | + struct ErrorWarningInfo |
1592 | + { |
1593 | + GError* error; |
1594 | + gchar* debug; |
1595 | + } error_warning_info; |
1596 | + struct Tag |
1597 | + { |
1598 | + GstTagList* tag_list; |
1599 | + } tag; |
1600 | + struct |
1601 | + { |
1602 | + gint percent; |
1603 | + } buffering; |
1604 | + struct |
1605 | + { |
1606 | + GstBufferingMode buffering_mode; |
1607 | + gint avg_in; |
1608 | + gint avg_out; |
1609 | + gint64 buffering_left; |
1610 | + } buffering_stats; |
1611 | + struct StateChanged |
1612 | + { |
1613 | + GstState old_state; |
1614 | + GstState new_state; |
1615 | + GstState pending_state; |
1616 | + } state_changed; |
1617 | + struct |
1618 | + { |
1619 | + gboolean active; |
1620 | + GstFormat format; |
1621 | + guint64 amount; |
1622 | + gdouble rate; |
1623 | + gboolean flush; |
1624 | + gboolean intermediate; |
1625 | + } step_start; |
1626 | + struct |
1627 | + { |
1628 | + GstFormat format; |
1629 | + guint64 amount; |
1630 | + gdouble rate; |
1631 | + gboolean flush; |
1632 | + gboolean intermediate; |
1633 | + guint64 duration; |
1634 | + gboolean eos; |
1635 | + } step_done; |
1636 | + struct |
1637 | + { |
1638 | + GstClock* clock; |
1639 | + gboolean ready; |
1640 | + } clock_provide; |
1641 | + struct |
1642 | + { |
1643 | + GstClock* clock; |
1644 | + } clock_lost; |
1645 | + struct |
1646 | + { |
1647 | + GstClock* clock; |
1648 | + } clock_new; |
1649 | + struct |
1650 | + { |
1651 | + GstFormat format; |
1652 | + gint64 position; |
1653 | + } segment_start; |
1654 | + struct |
1655 | + { |
1656 | + GstFormat format; |
1657 | + gint64 position; |
1658 | + } segment_done; |
1659 | + struct |
1660 | + { |
1661 | + GstClockTime running_time; |
1662 | + } async_done; |
1663 | + struct |
1664 | + { |
1665 | + gboolean live; |
1666 | + guint64 running_time; |
1667 | + guint64 stream_time; |
1668 | + guint64 timestamp; |
1669 | + guint64 duration; |
1670 | + } qos; |
1671 | + } detail; |
1672 | + std::function<void()> cleanup; |
1673 | + }; |
1674 | + |
1675 | + static GstBusSyncReply sync_handler( |
1676 | + GstBus* bus, |
1677 | + GstMessage* msg, |
1678 | + gpointer data) |
1679 | + { |
1680 | + (void) bus; |
1681 | + |
1682 | + auto thiz = static_cast<Bus*>(data); |
1683 | + Message message(msg); |
1684 | + thiz->on_new_message(message); |
1685 | + |
1686 | + return GST_BUS_DROP; |
1687 | + } |
1688 | + |
1689 | + Bus(GstBus* bus) : bus(bus) |
1690 | + { |
1691 | + if (!bus) |
1692 | + throw std::runtime_error("Cannot create Bus instance if underlying instance is NULL."); |
1693 | + |
1694 | + gst_bus_set_sync_handler( |
1695 | + bus, |
1696 | + Bus::sync_handler, |
1697 | + this, |
1698 | + nullptr); |
1699 | + } |
1700 | + |
1701 | + ~Bus() |
1702 | + { |
1703 | + gst_object_unref(bus); |
1704 | + } |
1705 | + |
1706 | + GstBus* bus; |
1707 | + com::ubuntu::music::Signal<Message> on_new_message; |
1708 | +}; |
1709 | +} |
1710 | + |
1711 | +#endif // GSTREAMER_BUS_H_ |
1712 | |
1713 | === added file 'src/com/ubuntu/music/gstreamer/engine.cpp' |
1714 | --- src/com/ubuntu/music/gstreamer/engine.cpp 1970-01-01 00:00:00 +0000 |
1715 | +++ src/com/ubuntu/music/gstreamer/engine.cpp 2013-11-11 13:09:24 +0000 |
1716 | @@ -0,0 +1,283 @@ |
1717 | +/* |
1718 | + * Copyright © 2013 Canonical Ltd. |
1719 | + * |
1720 | + * This program is free software: you can redistribute it and/or modify it |
1721 | + * under the terms of the GNU Lesser General Public License version 3, |
1722 | + * as published by the Free Software Foundation. |
1723 | + * |
1724 | + * This program is distributed in the hope that it will be useful, |
1725 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1726 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1727 | + * GNU Lesser General Public License for more details. |
1728 | + * |
1729 | + * You should have received a copy of the GNU Lesser General Public License |
1730 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1731 | + * |
1732 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1733 | + */ |
1734 | + |
1735 | +#include "bus.h" |
1736 | +#include "engine.h" |
1737 | +#include "meta_data_extractor.h" |
1738 | +#include "playbin.h" |
1739 | + |
1740 | +#include <cassert> |
1741 | + |
1742 | +namespace music = com::ubuntu::music; |
1743 | + |
1744 | +namespace gstreamer |
1745 | +{ |
1746 | +struct Init |
1747 | +{ |
1748 | + Init() |
1749 | + { |
1750 | + gst_init(nullptr, nullptr); |
1751 | + } |
1752 | + |
1753 | + ~Init() |
1754 | + { |
1755 | + gst_deinit(); |
1756 | + } |
1757 | +} init; |
1758 | +} |
1759 | + |
1760 | +struct gstreamer::Engine::Private |
1761 | +{ |
1762 | + void about_to_finish() |
1763 | + { |
1764 | + state = Engine::State::ready; |
1765 | + } |
1766 | + |
1767 | + void on_playbin_state_changed( |
1768 | + const gstreamer::Bus::Message::Detail::StateChanged&) |
1769 | + { |
1770 | + } |
1771 | + |
1772 | + void on_tag_available(const gstreamer::Bus::Message::Detail::Tag& tag) |
1773 | + { |
1774 | + music::Track::MetaData md; |
1775 | + |
1776 | + gst_tag_list_foreach( |
1777 | + tag.tag_list, |
1778 | + [](const GstTagList *list, |
1779 | + const gchar* tag, |
1780 | + gpointer user_data) |
1781 | + { |
1782 | + (void) list; |
1783 | + |
1784 | + static const std::map<std::string, std::string> gstreamer_to_mpris_tag_lut = |
1785 | + { |
1786 | + {GST_TAG_ALBUM, music::Engine::Xesam::album()}, |
1787 | + {GST_TAG_ALBUM_ARTIST, music::Engine::Xesam::album_artist()}, |
1788 | + {GST_TAG_ARTIST, music::Engine::Xesam::artist()}, |
1789 | + {GST_TAG_LYRICS, music::Engine::Xesam::as_text()}, |
1790 | + {GST_TAG_COMMENT, music::Engine::Xesam::comment()}, |
1791 | + {GST_TAG_COMPOSER, music::Engine::Xesam::composer()}, |
1792 | + {GST_TAG_DATE, music::Engine::Xesam::content_created()}, |
1793 | + {GST_TAG_ALBUM_VOLUME_NUMBER, music::Engine::Xesam::disc_number()}, |
1794 | + {GST_TAG_GENRE, music::Engine::Xesam::genre()}, |
1795 | + {GST_TAG_TITLE, music::Engine::Xesam::title()}, |
1796 | + {GST_TAG_TRACK_NUMBER, music::Engine::Xesam::track_number()}, |
1797 | + {GST_TAG_USER_RATING, music::Engine::Xesam::user_rating()} |
1798 | + }; |
1799 | + |
1800 | + auto md = static_cast<music::Track::MetaData*>(user_data); |
1801 | + std::stringstream ss; |
1802 | + |
1803 | + switch(gst_tag_get_type(tag)) |
1804 | + { |
1805 | + case G_TYPE_BOOLEAN: |
1806 | + { |
1807 | + gboolean value; |
1808 | + if (gst_tag_list_get_boolean(list, tag, &value)) |
1809 | + ss << value; |
1810 | + break; |
1811 | + } |
1812 | + case G_TYPE_INT: |
1813 | + { |
1814 | + gint value; |
1815 | + if (gst_tag_list_get_int(list, tag, &value)) |
1816 | + ss << value; |
1817 | + break; |
1818 | + } |
1819 | + case G_TYPE_UINT: |
1820 | + { |
1821 | + guint value; |
1822 | + if (gst_tag_list_get_uint(list, tag, &value)) |
1823 | + ss << value; |
1824 | + break; |
1825 | + } |
1826 | + case G_TYPE_INT64: |
1827 | + { |
1828 | + gint64 value; |
1829 | + if (gst_tag_list_get_int64(list, tag, &value)) |
1830 | + ss << value; |
1831 | + break; |
1832 | + } |
1833 | + case G_TYPE_UINT64: |
1834 | + { |
1835 | + guint64 value; |
1836 | + if (gst_tag_list_get_uint64(list, tag, &value)) |
1837 | + ss << value; |
1838 | + break; |
1839 | + } |
1840 | + case G_TYPE_FLOAT: |
1841 | + { |
1842 | + gfloat value; |
1843 | + if (gst_tag_list_get_float(list, tag, &value)) |
1844 | + ss << value; |
1845 | + break; |
1846 | + } |
1847 | + case G_TYPE_DOUBLE: |
1848 | + { |
1849 | + double value; |
1850 | + if (gst_tag_list_get_double(list, tag, &value)) |
1851 | + ss << value; |
1852 | + break; |
1853 | + } |
1854 | + case G_TYPE_STRING: |
1855 | + { |
1856 | + gchar* value; |
1857 | + if (gst_tag_list_get_string(list, tag, &value)) |
1858 | + { |
1859 | + ss << value; |
1860 | + g_free(value); |
1861 | + } |
1862 | + break; |
1863 | + } |
1864 | + default: |
1865 | + break; |
1866 | + } |
1867 | + |
1868 | + (*md).set( |
1869 | + (gstreamer_to_mpris_tag_lut.count(tag) > 0 ? gstreamer_to_mpris_tag_lut.at(tag) : tag), |
1870 | + ss.str()); |
1871 | + }, |
1872 | + &md); |
1873 | + |
1874 | + track_meta_data.set(std::make_tuple(playbin.uri(), md)); |
1875 | + } |
1876 | + |
1877 | + void on_volume_changed(const music::Engine::Volume& new_volume) |
1878 | + { |
1879 | + playbin.set_volume(new_volume.value); |
1880 | + } |
1881 | + |
1882 | + Private() |
1883 | + : meta_data_extractor(new gstreamer::MetaDataExtractor()), |
1884 | + volume(music::Engine::Volume(1.)), |
1885 | + about_to_finish_connection( |
1886 | + playbin.signals.about_to_finish.connect( |
1887 | + std::bind( |
1888 | + &Private::about_to_finish, |
1889 | + this))), |
1890 | + on_state_changed_connection( |
1891 | + playbin.signals.on_state_changed.connect( |
1892 | + std::bind( |
1893 | + &Private::on_playbin_state_changed, |
1894 | + this, |
1895 | + std::placeholders::_1))), |
1896 | + on_tag_available_connection( |
1897 | + playbin.signals.on_tag_available.connect( |
1898 | + std::bind( |
1899 | + &Private::on_tag_available, |
1900 | + this, |
1901 | + std::placeholders::_1))), |
1902 | + on_volume_changed_connection( |
1903 | + volume.changed().connect( |
1904 | + std::bind( |
1905 | + &Private::on_volume_changed, |
1906 | + this, |
1907 | + std::placeholders::_1))) |
1908 | + { |
1909 | + } |
1910 | + |
1911 | + std::shared_ptr<Engine::MetaDataExtractor> meta_data_extractor; |
1912 | + music::Property<Engine::State> state; |
1913 | + music::Property<std::tuple<music::Track::UriType, music::Track::MetaData>> track_meta_data; |
1914 | + music::Property<music::Engine::Volume> volume; |
1915 | + gstreamer::Playbin playbin; |
1916 | + music::ScopedConnection about_to_finish_connection; |
1917 | + music::ScopedConnection on_state_changed_connection; |
1918 | + music::ScopedConnection on_tag_available_connection; |
1919 | + music::ScopedConnection on_volume_changed_connection; |
1920 | +}; |
1921 | + |
1922 | +gstreamer::Engine::Engine() : d(new Private{}) |
1923 | +{ |
1924 | + d->state = music::Engine::State::ready; |
1925 | +} |
1926 | + |
1927 | +gstreamer::Engine::~Engine() |
1928 | +{ |
1929 | + stop(); |
1930 | +} |
1931 | + |
1932 | +const std::shared_ptr<music::Engine::MetaDataExtractor>& gstreamer::Engine::meta_data_extractor() const |
1933 | +{ |
1934 | + return d->meta_data_extractor; |
1935 | +} |
1936 | + |
1937 | +const music::Property<music::Engine::State>& gstreamer::Engine::state() const |
1938 | +{ |
1939 | + return d->state; |
1940 | +} |
1941 | + |
1942 | +bool gstreamer::Engine::open_resource_for_uri(const music::Track::UriType& uri) |
1943 | +{ |
1944 | + d->playbin.set_uri(uri); |
1945 | + return true; |
1946 | +} |
1947 | + |
1948 | +bool gstreamer::Engine::play() |
1949 | +{ |
1950 | + auto result = d->playbin.set_state_and_wait(GST_STATE_PLAYING); |
1951 | + |
1952 | + if (result) |
1953 | + { |
1954 | + d->state = music::Engine::State::playing; |
1955 | + } |
1956 | + |
1957 | + return result; |
1958 | +} |
1959 | + |
1960 | +bool gstreamer::Engine::stop() |
1961 | +{ |
1962 | + auto result = d->playbin.set_state_and_wait(GST_STATE_NULL); |
1963 | + |
1964 | + if (result) |
1965 | + d->state = music::Engine::State::stopped; |
1966 | + |
1967 | + return result; |
1968 | +} |
1969 | + |
1970 | +bool gstreamer::Engine::pause() |
1971 | +{ |
1972 | + auto result = d->playbin.set_state_and_wait(GST_STATE_PAUSED); |
1973 | + |
1974 | + if (result) |
1975 | + d->state = music::Engine::State::paused; |
1976 | + |
1977 | + return result; |
1978 | +} |
1979 | + |
1980 | +bool gstreamer::Engine::seek_to(const std::chrono::microseconds& ts) |
1981 | +{ |
1982 | + return d->playbin.seek(ts); |
1983 | +} |
1984 | + |
1985 | +const com::ubuntu::music::Property<com::ubuntu::music::Engine::Volume>& gstreamer::Engine::volume() const |
1986 | +{ |
1987 | + return d->volume; |
1988 | +} |
1989 | + |
1990 | +com::ubuntu::music::Property<com::ubuntu::music::Engine::Volume>& gstreamer::Engine::volume() |
1991 | +{ |
1992 | + return d->volume; |
1993 | +} |
1994 | + |
1995 | +const music::Property<std::tuple<music::Track::UriType, music::Track::MetaData>>& |
1996 | +gstreamer::Engine::track_meta_data() const |
1997 | +{ |
1998 | + return d->track_meta_data; |
1999 | +} |
2000 | |
2001 | === added file 'src/com/ubuntu/music/gstreamer/engine.h' |
2002 | --- src/com/ubuntu/music/gstreamer/engine.h 1970-01-01 00:00:00 +0000 |
2003 | +++ src/com/ubuntu/music/gstreamer/engine.h 2013-11-11 13:09:24 +0000 |
2004 | @@ -0,0 +1,53 @@ |
2005 | +/* |
2006 | + * Copyright © 2013 Canonical Ltd. |
2007 | + * |
2008 | + * This program is free software: you can redistribute it and/or modify it |
2009 | + * under the terms of the GNU Lesser General Public License version 3, |
2010 | + * as published by the Free Software Foundation. |
2011 | + * |
2012 | + * This program is distributed in the hope that it will be useful, |
2013 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2014 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2015 | + * GNU Lesser General Public License for more details. |
2016 | + * |
2017 | + * You should have received a copy of the GNU Lesser General Public License |
2018 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2019 | + * |
2020 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2021 | + */ |
2022 | +#ifndef COM_UBUNTU_MUSIC_GSTREAMER_ENGINE_H_ |
2023 | +#define COM_UBUNTU_MUSIC_GSTREAMER_ENGINE_H_ |
2024 | + |
2025 | +#include "../engine.h" |
2026 | + |
2027 | +namespace gstreamer |
2028 | +{ |
2029 | +class Engine : public com::ubuntu::music::Engine |
2030 | +{ |
2031 | +public: |
2032 | + Engine(); |
2033 | + ~Engine(); |
2034 | + |
2035 | + const std::shared_ptr<MetaDataExtractor>& meta_data_extractor() const; |
2036 | + |
2037 | + const com::ubuntu::music::Property<State>& state() const; |
2038 | + |
2039 | + bool open_resource_for_uri(const com::ubuntu::music::Track::UriType& uri); |
2040 | + |
2041 | + bool play(); |
2042 | + bool stop(); |
2043 | + bool pause(); |
2044 | + bool seek_to(const std::chrono::microseconds& ts); |
2045 | + |
2046 | + const com::ubuntu::music::Property<com::ubuntu::music::Engine::Volume>& volume() const; |
2047 | + com::ubuntu::music::Property<com::ubuntu::music::Engine::Volume>& volume(); |
2048 | + |
2049 | + const com::ubuntu::music::Property<std::tuple<com::ubuntu::music::Track::UriType, com::ubuntu::music::Track::MetaData>>& track_meta_data() const; |
2050 | + |
2051 | +private: |
2052 | + struct Private; |
2053 | + std::unique_ptr<Private> d; |
2054 | +}; |
2055 | +} |
2056 | + |
2057 | +#endif // COM_UBUNTU_MUSIC_GSTREAMER_ENGINE_H_ |
2058 | |
2059 | === added file 'src/com/ubuntu/music/gstreamer/meta_data_extractor.h' |
2060 | --- src/com/ubuntu/music/gstreamer/meta_data_extractor.h 1970-01-01 00:00:00 +0000 |
2061 | +++ src/com/ubuntu/music/gstreamer/meta_data_extractor.h 2013-11-11 13:09:24 +0000 |
2062 | @@ -0,0 +1,221 @@ |
2063 | +/* |
2064 | + * Copyright © 2013 Canonical Ltd. |
2065 | + * |
2066 | + * This program is free software: you can redistribute it and/or modify it |
2067 | + * under the terms of the GNU Lesser General Public License version 3, |
2068 | + * as published by the Free Software Foundation. |
2069 | + * |
2070 | + * This program is distributed in the hope that it will be useful, |
2071 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2072 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2073 | + * GNU Lesser General Public License for more details. |
2074 | + * |
2075 | + * You should have received a copy of the GNU Lesser General Public License |
2076 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2077 | + * |
2078 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2079 | + */ |
2080 | + |
2081 | +#ifndef GSTREAMER_META_DATA_EXTRACTOR_H_ |
2082 | +#define GSTREAMER_META_DATA_EXTRACTOR_H_ |
2083 | + |
2084 | +#include "../engine.h" |
2085 | + |
2086 | +#include "bus.h" |
2087 | + |
2088 | +#include <gst/gst.h> |
2089 | + |
2090 | +#include <exception> |
2091 | +#include <future> |
2092 | + |
2093 | +namespace gstreamer |
2094 | +{ |
2095 | +class MetaDataExtractor : public com::ubuntu::music::Engine::MetaDataExtractor |
2096 | +{ |
2097 | +public: |
2098 | + MetaDataExtractor() |
2099 | + : pipe(gst_pipeline_new("meta_data_extractor_pipeline")), |
2100 | + decoder(gst_element_factory_make ("uridecodebin", NULL)), |
2101 | + bus(GST_ELEMENT_BUS(pipe)) |
2102 | + { |
2103 | + gst_bin_add(GST_BIN(pipe), decoder); |
2104 | + |
2105 | + auto sink = gst_element_factory_make ("fakesink", NULL); |
2106 | + gst_bin_add (GST_BIN (pipe), sink); |
2107 | + |
2108 | + g_signal_connect (decoder, "pad-added", G_CALLBACK (on_new_pad), sink); |
2109 | + } |
2110 | + |
2111 | + ~MetaDataExtractor() |
2112 | + { |
2113 | + gst_element_set_state(pipe, GST_STATE_NULL); |
2114 | + // gst_object_unref(pipe); |
2115 | + } |
2116 | + |
2117 | + com::ubuntu::music::Track::MetaData meta_data_for_track_with_uri(const com::ubuntu::music::Track::UriType& uri) |
2118 | + { |
2119 | + if (!gst_uri_is_valid(uri.c_str())) |
2120 | + throw std::runtime_error("Invalid uri"); |
2121 | + |
2122 | + com::ubuntu::music::Track::MetaData meta_data; |
2123 | + std::promise<com::ubuntu::music::Track::MetaData> promise; |
2124 | + std::future<com::ubuntu::music::Track::MetaData> future{promise.get_future()}; |
2125 | + |
2126 | + com::ubuntu::music::ScopedConnection on_new_message_connection |
2127 | + { |
2128 | + bus.on_new_message.connect( |
2129 | + [&](const gstreamer::Bus::Message& msg) |
2130 | + { |
2131 | + std::cout << __PRETTY_FUNCTION__ << gst_message_type_get_name(msg.type) << std::endl; |
2132 | + if (msg.type == GST_MESSAGE_TAG) |
2133 | + { |
2134 | + MetaDataExtractor::on_tag_available(msg.detail.tag, meta_data); |
2135 | + } else if (msg.type == GST_MESSAGE_ASYNC_DONE) |
2136 | + { |
2137 | + promise.set_value(meta_data); |
2138 | + } |
2139 | + }) |
2140 | + }; |
2141 | + |
2142 | + g_object_set(decoder, "uri", uri.c_str(), NULL); |
2143 | + gst_element_set_state(pipe, GST_STATE_PAUSED); |
2144 | + |
2145 | + if (std::future_status::ready != future.wait_for(std::chrono::seconds(2))) |
2146 | + { |
2147 | + gst_element_set_state(pipe, GST_STATE_NULL); |
2148 | + throw std::runtime_error("Problem extracting meta data for track"); |
2149 | + } else |
2150 | + { |
2151 | + gst_element_set_state(pipe, GST_STATE_NULL); |
2152 | + } |
2153 | + |
2154 | + return future.get(); |
2155 | + } |
2156 | + |
2157 | +private: |
2158 | + static void on_new_pad(GstElement*, GstPad* pad, GstElement* fakesink) |
2159 | + { |
2160 | + GstPad *sinkpad; |
2161 | + |
2162 | + sinkpad = gst_element_get_static_pad (fakesink, "sink"); |
2163 | + |
2164 | + if (!gst_pad_is_linked (sinkpad)) { |
2165 | + if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK) |
2166 | + g_error ("Failed to link pads!"); |
2167 | + } |
2168 | + |
2169 | + gst_object_unref (sinkpad); |
2170 | + } |
2171 | + |
2172 | + static void on_tag_available( |
2173 | + const gstreamer::Bus::Message::Detail::Tag& tag, |
2174 | + com::ubuntu::music::Track::MetaData& md) |
2175 | + { |
2176 | + namespace music = com::ubuntu::music; |
2177 | + |
2178 | + gst_tag_list_foreach( |
2179 | + tag.tag_list, |
2180 | + [](const GstTagList *list, |
2181 | + const gchar* tag, |
2182 | + gpointer user_data) |
2183 | + { |
2184 | + (void) list; |
2185 | + |
2186 | + static const std::map<std::string, std::string> gstreamer_to_mpris_tag_lut = |
2187 | + { |
2188 | + {GST_TAG_ALBUM, music::Engine::Xesam::album()}, |
2189 | + {GST_TAG_ALBUM_ARTIST, music::Engine::Xesam::album_artist()}, |
2190 | + {GST_TAG_ARTIST, music::Engine::Xesam::artist()}, |
2191 | + {GST_TAG_LYRICS, music::Engine::Xesam::as_text()}, |
2192 | + {GST_TAG_COMMENT, music::Engine::Xesam::comment()}, |
2193 | + {GST_TAG_COMPOSER, music::Engine::Xesam::composer()}, |
2194 | + {GST_TAG_DATE, music::Engine::Xesam::content_created()}, |
2195 | + {GST_TAG_ALBUM_VOLUME_NUMBER, music::Engine::Xesam::disc_number()}, |
2196 | + {GST_TAG_GENRE, music::Engine::Xesam::genre()}, |
2197 | + {GST_TAG_TITLE, music::Engine::Xesam::title()}, |
2198 | + {GST_TAG_TRACK_NUMBER, music::Engine::Xesam::track_number()}, |
2199 | + {GST_TAG_USER_RATING, music::Engine::Xesam::user_rating()} |
2200 | + }; |
2201 | + |
2202 | + auto md = static_cast<music::Track::MetaData*>(user_data); |
2203 | + std::stringstream ss; |
2204 | + |
2205 | + switch(gst_tag_get_type(tag)) |
2206 | + { |
2207 | + case G_TYPE_BOOLEAN: |
2208 | + { |
2209 | + gboolean value; |
2210 | + if (gst_tag_list_get_boolean(list, tag, &value)) |
2211 | + ss << value; |
2212 | + break; |
2213 | + } |
2214 | + case G_TYPE_INT: |
2215 | + { |
2216 | + gint value; |
2217 | + if (gst_tag_list_get_int(list, tag, &value)) |
2218 | + ss << value; |
2219 | + break; |
2220 | + } |
2221 | + case G_TYPE_UINT: |
2222 | + { |
2223 | + guint value; |
2224 | + if (gst_tag_list_get_uint(list, tag, &value)) |
2225 | + ss << value; |
2226 | + break; |
2227 | + } |
2228 | + case G_TYPE_INT64: |
2229 | + { |
2230 | + gint64 value; |
2231 | + if (gst_tag_list_get_int64(list, tag, &value)) |
2232 | + ss << value; |
2233 | + break; |
2234 | + } |
2235 | + case G_TYPE_UINT64: |
2236 | + { |
2237 | + guint64 value; |
2238 | + if (gst_tag_list_get_uint64(list, tag, &value)) |
2239 | + ss << value; |
2240 | + break; |
2241 | + } |
2242 | + case G_TYPE_FLOAT: |
2243 | + { |
2244 | + gfloat value; |
2245 | + if (gst_tag_list_get_float(list, tag, &value)) |
2246 | + ss << value; |
2247 | + break; |
2248 | + } |
2249 | + case G_TYPE_DOUBLE: |
2250 | + { |
2251 | + double value; |
2252 | + if (gst_tag_list_get_double(list, tag, &value)) |
2253 | + ss << value; |
2254 | + break; |
2255 | + } |
2256 | + case G_TYPE_STRING: |
2257 | + { |
2258 | + gchar* value; |
2259 | + if (gst_tag_list_get_string(list, tag, &value)) |
2260 | + { |
2261 | + ss << value; |
2262 | + g_free(value); |
2263 | + } |
2264 | + break; |
2265 | + } |
2266 | + default: |
2267 | + break; |
2268 | + } |
2269 | + |
2270 | + (*md).set( |
2271 | + (gstreamer_to_mpris_tag_lut.count(tag) > 0 ? gstreamer_to_mpris_tag_lut.at(tag) : tag), |
2272 | + ss.str()); |
2273 | + }, |
2274 | + &md); |
2275 | + } |
2276 | + |
2277 | + GstElement* pipe; |
2278 | + GstElement* decoder; |
2279 | + Bus bus; |
2280 | +}; |
2281 | +} |
2282 | + |
2283 | +#endif // GSTREAMER_META_DATA_EXTRACTOR_H_ |
2284 | |
2285 | === added file 'src/com/ubuntu/music/gstreamer/playbin.h' |
2286 | --- src/com/ubuntu/music/gstreamer/playbin.h 1970-01-01 00:00:00 +0000 |
2287 | +++ src/com/ubuntu/music/gstreamer/playbin.h 2013-11-11 13:09:24 +0000 |
2288 | @@ -0,0 +1,219 @@ |
2289 | +/* |
2290 | + * Copyright © 2013 Canonical Ltd. |
2291 | + * |
2292 | + * This program is free software: you can redistribute it and/or modify it |
2293 | + * under the terms of the GNU Lesser General Public License version 3, |
2294 | + * as published by the Free Software Foundation. |
2295 | + * |
2296 | + * This program is distributed in the hope that it will be useful, |
2297 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2298 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2299 | + * GNU Lesser General Public License for more details. |
2300 | + * |
2301 | + * You should have received a copy of the GNU Lesser General Public License |
2302 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2303 | + * |
2304 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2305 | + */ |
2306 | + |
2307 | +#ifndef GSTREAMER_PLAYBIN_H_ |
2308 | +#define GSTREAMER_PLAYBIN_H_ |
2309 | + |
2310 | +#include "bus.h" |
2311 | + |
2312 | +#include <gst/gst.h> |
2313 | + |
2314 | +#include <chrono> |
2315 | +#include <string> |
2316 | + |
2317 | +namespace gstreamer |
2318 | +{ |
2319 | +struct Playbin |
2320 | +{ |
2321 | + enum PlayFlags |
2322 | + { |
2323 | + GST_PLAY_FLAG_VIDEO = (1 << 0), |
2324 | + GST_PLAY_FLAG_AUDIO = (1 << 1), |
2325 | + GST_PLAY_FLAG_TEXT = (1 << 2) |
2326 | + }; |
2327 | + |
2328 | + static const std::string& pipeline_name() |
2329 | + { |
2330 | + static const std::string s{"playbin"}; |
2331 | + return s; |
2332 | + } |
2333 | + |
2334 | + static void about_to_finish(GstElement*, |
2335 | + gpointer user_data) |
2336 | + { auto thiz = static_cast<Playbin*>(user_data); |
2337 | + |
2338 | + thiz->signals.about_to_finish(); |
2339 | + } |
2340 | + |
2341 | + Playbin() |
2342 | + : pipeline(gst_element_factory_make("playbin", pipeline_name().c_str())), |
2343 | + bus{gst_element_get_bus(pipeline)}, |
2344 | + on_new_message_connection( |
2345 | + bus.on_new_message.connect( |
2346 | + std::bind( |
2347 | + &Playbin::on_new_message, |
2348 | + this, |
2349 | + std::placeholders::_1))) |
2350 | + { |
2351 | + if (!pipeline) |
2352 | + throw std::runtime_error("Could not create pipeline for playbin."); |
2353 | + |
2354 | + setup_pipeline_for_audio(); |
2355 | + |
2356 | + g_signal_connect( |
2357 | + pipeline, |
2358 | + "about-to-finish", |
2359 | + G_CALLBACK(about_to_finish), |
2360 | + this |
2361 | + ); |
2362 | + |
2363 | + } |
2364 | + |
2365 | + ~Playbin() |
2366 | + { |
2367 | + if (pipeline) |
2368 | + gst_object_unref(pipeline); |
2369 | + } |
2370 | + |
2371 | + void on_new_message(const Bus::Message& message) |
2372 | + { |
2373 | + switch(message.type) |
2374 | + { |
2375 | + case GST_MESSAGE_ERROR: |
2376 | + signals.on_error(message.detail.error_warning_info); |
2377 | + break; |
2378 | + case GST_MESSAGE_WARNING: |
2379 | + signals.on_warning(message.detail.error_warning_info); |
2380 | + break; |
2381 | + case GST_MESSAGE_INFO: |
2382 | + signals.on_info(message.detail.error_warning_info); |
2383 | + break; |
2384 | + case GST_MESSAGE_TAG: |
2385 | + signals.on_tag_available(message.detail.tag); |
2386 | + break; |
2387 | + case GST_MESSAGE_STATE_CHANGED: |
2388 | + signals.on_state_changed(message.detail.state_changed); |
2389 | + break; |
2390 | + default: |
2391 | + break; |
2392 | + } |
2393 | + } |
2394 | + |
2395 | + gstreamer::Bus& message_bus() |
2396 | + { |
2397 | + return bus; |
2398 | + } |
2399 | + |
2400 | + void setup_pipeline_for_audio() |
2401 | + { |
2402 | + gint flags; |
2403 | + g_object_get(pipeline, "flags", &flags, nullptr); |
2404 | + flags |= GST_PLAY_FLAG_AUDIO; |
2405 | + flags &= ~GST_PLAY_FLAG_TEXT; |
2406 | + flags &= ~GST_PLAY_FLAG_VIDEO; |
2407 | + g_object_set (pipeline, "flags", flags, nullptr); |
2408 | + |
2409 | + if (::getenv("COM_UBUNTU_MUSIC_SERVICE_AUDIO_SINK_NAME") != nullptr) |
2410 | + { |
2411 | + auto audio_sink = gst_element_factory_make ( |
2412 | + ::getenv("COM_UBUNTU_MUSIC_SERVICE_AUDIO_SINK_NAME"), |
2413 | + "audio-sink"); |
2414 | + |
2415 | + g_object_set( |
2416 | + pipeline, |
2417 | + "audio-sink", |
2418 | + audio_sink, |
2419 | + NULL); |
2420 | + } |
2421 | + } |
2422 | + |
2423 | + void set_volume(double new_volume) |
2424 | + { |
2425 | + g_object_set( |
2426 | + pipeline, |
2427 | + "volume", |
2428 | + new_volume, |
2429 | + NULL); |
2430 | + } |
2431 | + |
2432 | + void set_uri(const std::string& uri) |
2433 | + { |
2434 | + g_object_set( |
2435 | + pipeline, |
2436 | + "uri", |
2437 | + uri.c_str(), |
2438 | + NULL); |
2439 | + } |
2440 | + |
2441 | + std::string uri() const |
2442 | + { |
2443 | + gchar* data = nullptr; |
2444 | + g_object_get(pipeline, "current-uri", &data, nullptr); |
2445 | + |
2446 | + std::string result((data == nullptr ? "" : data)); |
2447 | + g_free(data); |
2448 | + |
2449 | + return result; |
2450 | + } |
2451 | + |
2452 | + bool set_state_and_wait(GstState new_state) |
2453 | + { |
2454 | + static const std::chrono::nanoseconds state_change_timeout |
2455 | + { |
2456 | + // We choose a quite high value here as tests are run under valgrind |
2457 | + // and gstreamer pipeline setup/state changes take longer in that scenario. |
2458 | + // The value does not negatively impact runtime performance. |
2459 | + std::chrono::milliseconds{5000} |
2460 | + }; |
2461 | + |
2462 | + auto ret = gst_element_set_state(pipeline, new_state); |
2463 | + bool result = false; GstState current, pending; |
2464 | + switch(ret) |
2465 | + { |
2466 | + case GST_STATE_CHANGE_FAILURE: |
2467 | + result = false; break; |
2468 | + case GST_STATE_CHANGE_NO_PREROLL: |
2469 | + case GST_STATE_CHANGE_SUCCESS: |
2470 | + result = true; break; |
2471 | + case GST_STATE_CHANGE_ASYNC: |
2472 | + result = GST_STATE_CHANGE_SUCCESS == gst_element_get_state( |
2473 | + pipeline, |
2474 | + ¤t, |
2475 | + &pending, |
2476 | + state_change_timeout.count()); |
2477 | + break; |
2478 | + } |
2479 | + |
2480 | + return result; |
2481 | + } |
2482 | + |
2483 | + bool seek(const std::chrono::nanoseconds& ns) |
2484 | + { |
2485 | + return gst_element_seek_simple( |
2486 | + pipeline, |
2487 | + GST_FORMAT_TIME, |
2488 | + (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), |
2489 | + ns.count()); |
2490 | + } |
2491 | + |
2492 | + GstElement* pipeline; |
2493 | + gstreamer::Bus bus; |
2494 | + com::ubuntu::music::Connection on_new_message_connection; |
2495 | + struct |
2496 | + { |
2497 | + com::ubuntu::music::Signal<void> about_to_finish; |
2498 | + com::ubuntu::music::Signal<Bus::Message::Detail::ErrorWarningInfo> on_error; |
2499 | + com::ubuntu::music::Signal<Bus::Message::Detail::ErrorWarningInfo> on_warning; |
2500 | + com::ubuntu::music::Signal<Bus::Message::Detail::ErrorWarningInfo> on_info; |
2501 | + com::ubuntu::music::Signal<Bus::Message::Detail::Tag> on_tag_available; |
2502 | + com::ubuntu::music::Signal<Bus::Message::Detail::StateChanged> on_state_changed; |
2503 | + } signals; |
2504 | +}; |
2505 | +} |
2506 | + |
2507 | +#endif // GSTREAMER_PLAYBIN_H_ |
2508 | |
2509 | === added directory 'src/com/ubuntu/music/mpris' |
2510 | === added file 'src/com/ubuntu/music/mpris/macros.h' |
2511 | --- src/com/ubuntu/music/mpris/macros.h 1970-01-01 00:00:00 +0000 |
2512 | +++ src/com/ubuntu/music/mpris/macros.h 2013-11-11 13:09:24 +0000 |
2513 | @@ -0,0 +1,79 @@ |
2514 | +/* |
2515 | + * Copyright © 2013 Canonical Ltd. |
2516 | + * |
2517 | + * This program is free software: you can redistribute it and/or modify it |
2518 | + * under the terms of the GNU Lesser General Public License version 3, |
2519 | + * as published by the Free Software Foundation. |
2520 | + * |
2521 | + * This program is distributed in the hope that it will be useful, |
2522 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2523 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2524 | + * GNU Lesser General Public License for more details. |
2525 | + * |
2526 | + * You should have received a copy of the GNU Lesser General Public License |
2527 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2528 | + * |
2529 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2530 | + */ |
2531 | + |
2532 | +#ifndef MPRIS_MACROS_H_ |
2533 | +#define MPRIS_MACROS_H_ |
2534 | + |
2535 | +#include <org/freedesktop/dbus/types/object_path.h> |
2536 | + |
2537 | +#include <chrono> |
2538 | +#include <string> |
2539 | + |
2540 | +#define SECONDS(seconds) std::chrono::seconds{seconds}; |
2541 | + |
2542 | +#define METHOD(Name, Itf, Timeout) \ |
2543 | + struct Name \ |
2544 | + { \ |
2545 | + typedef Itf Interface; \ |
2546 | + inline static const std::string& name() \ |
2547 | + { \ |
2548 | + static const std::string s{#Name}; \ |
2549 | + return s; \ |
2550 | + } \ |
2551 | + inline static const std::chrono::milliseconds default_timeout() { return std::chrono::milliseconds{2000}; } \ |
2552 | + };\ |
2553 | + |
2554 | +#define SIGNAL(Name, Itf, ArgType) \ |
2555 | + struct Name \ |
2556 | + { \ |
2557 | + inline static std::string name() \ |
2558 | + { \ |
2559 | + return #Name; \ |
2560 | + }; \ |
2561 | + typedef Itf Interface; \ |
2562 | + typedef ArgType ArgumentType; \ |
2563 | + };\ |
2564 | + |
2565 | +#define READABLE_PROPERTY(Name, Itf, Type) \ |
2566 | + struct Name \ |
2567 | + { \ |
2568 | + inline static std::string name() \ |
2569 | + { \ |
2570 | + return #Name; \ |
2571 | + }; \ |
2572 | + typedef Itf Interface; \ |
2573 | + typedef Type ValueType; \ |
2574 | + static const bool readable = true; \ |
2575 | + static const bool writable = false; \ |
2576 | + }; \ |
2577 | + |
2578 | +#define WRITABLE_PROPERTY(Name, Itf, Type) \ |
2579 | + struct Name \ |
2580 | + { \ |
2581 | + inline static std::string name() \ |
2582 | + { \ |
2583 | + return #Name; \ |
2584 | + }; \ |
2585 | + typedef Itf Interface; \ |
2586 | + typedef Type ValueType; \ |
2587 | + static const bool readable = true; \ |
2588 | + static const bool writable = true; \ |
2589 | + }; \ |
2590 | + |
2591 | +#endif // MPRIS_MACROS_H_ |
2592 | + |
2593 | |
2594 | === added file 'src/com/ubuntu/music/mpris/player.h' |
2595 | --- src/com/ubuntu/music/mpris/player.h 1970-01-01 00:00:00 +0000 |
2596 | +++ src/com/ubuntu/music/mpris/player.h 2013-11-11 13:09:24 +0000 |
2597 | @@ -0,0 +1,85 @@ |
2598 | +/* |
2599 | + * Copyright © 2013 Canonical Ltd. |
2600 | + * |
2601 | + * This program is free software: you can redistribute it and/or modify it |
2602 | + * under the terms of the GNU Lesser General Public License version 3, |
2603 | + * as published by the Free Software Foundation. |
2604 | + * |
2605 | + * This program is distributed in the hope that it will be useful, |
2606 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2607 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2608 | + * GNU Lesser General Public License for more details. |
2609 | + * |
2610 | + * You should have received a copy of the GNU Lesser General Public License |
2611 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2612 | + * |
2613 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2614 | + */ |
2615 | + |
2616 | +#ifndef MPRIS_PLAYER_H_ |
2617 | +#define MPRIS_PLAYER_H_ |
2618 | + |
2619 | +#include <com/ubuntu/music/track.h> |
2620 | + |
2621 | +#include "macros.h" |
2622 | + |
2623 | +#include <org/freedesktop/dbus/types/any.h> |
2624 | +#include <org/freedesktop/dbus/types/object_path.h> |
2625 | +#include <org/freedesktop/dbus/types/variant.h> |
2626 | + |
2627 | +#include <boost/utility/identity_type.hpp> |
2628 | + |
2629 | +#include <string> |
2630 | +#include <tuple> |
2631 | +#include <vector> |
2632 | + |
2633 | +namespace dbus = org::freedesktop::dbus; |
2634 | + |
2635 | +namespace mpris |
2636 | +{ |
2637 | +struct Player |
2638 | +{ |
2639 | + static const std::string& name() |
2640 | + { |
2641 | + static const std::string s{"com.ubuntu.music.Service.Player"}; |
2642 | + return s; |
2643 | + } |
2644 | + |
2645 | + METHOD(Next, Player, std::chrono::seconds(1)) |
2646 | + METHOD(Previous, Player, std::chrono::seconds(1)) |
2647 | + METHOD(Pause, Player, std::chrono::seconds(1)) |
2648 | + METHOD(PlayPause, Player, std::chrono::seconds(1)) |
2649 | + METHOD(Stop, Player, std::chrono::seconds(1)) |
2650 | + METHOD(Play, Player, std::chrono::seconds(1)) |
2651 | + METHOD(Seek, Player, std::chrono::seconds(1)) |
2652 | + METHOD(SetPosition, Player, std::chrono::seconds(1)) |
2653 | + METHOD(OpenUri, Player, std::chrono::seconds(1)) |
2654 | + |
2655 | + struct Signals |
2656 | + { |
2657 | + SIGNAL(Seeked, Player, uint64_t) |
2658 | + }; |
2659 | + |
2660 | + struct Properties |
2661 | + { |
2662 | + READABLE_PROPERTY(PlaybackStatus, Player, std::string) |
2663 | + WRITABLE_PROPERTY(LoopStatus, Player, std::string) |
2664 | + WRITABLE_PROPERTY(PlaybackRate, Player, double) |
2665 | + WRITABLE_PROPERTY(Rate, Player, double) |
2666 | + WRITABLE_PROPERTY(Shuffle, Player, bool) |
2667 | + READABLE_PROPERTY(MetaData, Player, BOOST_IDENTITY_TYPE((std::map<std::string, std::string>))) |
2668 | + WRITABLE_PROPERTY(Volume, Player, double) |
2669 | + READABLE_PROPERTY(Position, Player, uint64_t) |
2670 | + READABLE_PROPERTY(MinimumRate, Player, double) |
2671 | + READABLE_PROPERTY(MaximumRate, Player, double) |
2672 | + READABLE_PROPERTY(CanGoNext, Player, bool) |
2673 | + READABLE_PROPERTY(CanGoPrevious, Player, bool) |
2674 | + READABLE_PROPERTY(CanPlay, Player, bool) |
2675 | + READABLE_PROPERTY(CanPause, Player, bool) |
2676 | + READABLE_PROPERTY(CanSeek, Player, bool) |
2677 | + READABLE_PROPERTY(CanControl, Player, bool) |
2678 | + }; |
2679 | +}; |
2680 | +} |
2681 | + |
2682 | +#endif // MPRIS_PLAYER_H_ |
2683 | |
2684 | === added file 'src/com/ubuntu/music/mpris/service.h' |
2685 | --- src/com/ubuntu/music/mpris/service.h 1970-01-01 00:00:00 +0000 |
2686 | +++ src/com/ubuntu/music/mpris/service.h 2013-11-11 13:09:24 +0000 |
2687 | @@ -0,0 +1,56 @@ |
2688 | +/* |
2689 | + * Copyright © 2013 Canonical Ltd. |
2690 | + * |
2691 | + * This program is free software: you can redistribute it and/or modify it |
2692 | + * under the terms of the GNU Lesser General Public License version 3, |
2693 | + * as published by the Free Software Foundation. |
2694 | + * |
2695 | + * This program is distributed in the hope that it will be useful, |
2696 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2697 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2698 | + * GNU Lesser General Public License for more details. |
2699 | + * |
2700 | + * You should have received a copy of the GNU Lesser General Public License |
2701 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2702 | + * |
2703 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2704 | + */ |
2705 | + |
2706 | +#ifndef MPRIS_SERVICE_H_ |
2707 | +#define MPRIS_SERVICE_H_ |
2708 | + |
2709 | +#include "macros.h" |
2710 | + |
2711 | +#include <chrono> |
2712 | +#include <string> |
2713 | + |
2714 | +namespace mpris |
2715 | +{ |
2716 | +struct Service |
2717 | +{ |
2718 | + static const std::string& name() |
2719 | + { |
2720 | + static const std::string s{"com.ubuntu.music.Service"}; |
2721 | + return s; |
2722 | + } |
2723 | + |
2724 | + struct Errors |
2725 | + { |
2726 | + struct CreatingSession |
2727 | + { |
2728 | + static const std::string& name() |
2729 | + { |
2730 | + static const std::string s |
2731 | + { |
2732 | + "com.ubuntu.music.Service.Error.CreatingSession" |
2733 | + }; |
2734 | + return s; |
2735 | + } |
2736 | + }; |
2737 | + }; |
2738 | + |
2739 | + METHOD(CreateSession, Service, std::chrono::seconds(1)) |
2740 | +}; |
2741 | +} |
2742 | + |
2743 | +#endif // MPRIS_SERVICE_H_ |
2744 | |
2745 | === added file 'src/com/ubuntu/music/mpris/track_list.h' |
2746 | --- src/com/ubuntu/music/mpris/track_list.h 1970-01-01 00:00:00 +0000 |
2747 | +++ src/com/ubuntu/music/mpris/track_list.h 2013-11-11 13:09:24 +0000 |
2748 | @@ -0,0 +1,88 @@ |
2749 | +/* |
2750 | + * Copyright © 2013 Canonical Ltd. |
2751 | + * |
2752 | + * This program is free software: you can redistribute it and/or modify it |
2753 | + * under the terms of the GNU Lesser General Public License version 3, |
2754 | + * as published by the Free Software Foundation. |
2755 | + * |
2756 | + * This program is distributed in the hope that it will be useful, |
2757 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2758 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2759 | + * GNU Lesser General Public License for more details. |
2760 | + * |
2761 | + * You should have received a copy of the GNU Lesser General Public License |
2762 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2763 | + * |
2764 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2765 | + */ |
2766 | + |
2767 | +#ifndef MPRIS_TRACK_LIST_H_ |
2768 | +#define MPRIS_TRACK_LIST_H_ |
2769 | + |
2770 | +#include "macros.h" |
2771 | + |
2772 | +#include <org/freedesktop/dbus/types/any.h> |
2773 | +#include <org/freedesktop/dbus/types/object_path.h> |
2774 | +#include <org/freedesktop/dbus/types/variant.h> |
2775 | + |
2776 | +#include <string> |
2777 | +#include <tuple> |
2778 | +#include <vector> |
2779 | + |
2780 | +namespace dbus = org::freedesktop::dbus; |
2781 | + |
2782 | +namespace mpris |
2783 | +{ |
2784 | +struct TrackList |
2785 | +{ |
2786 | + static const std::string& name() |
2787 | + { |
2788 | + static const std::string s{"com.ubuntu.music.Service.Player.TrackList"}; |
2789 | + return s; |
2790 | + } |
2791 | + |
2792 | + METHOD(GetTracksMetadata, TrackList, SECONDS(1)) |
2793 | + METHOD(AddTrack, TrackList, SECONDS(1)) |
2794 | + METHOD(RemoveTrack, TrackList, SECONDS(1)) |
2795 | + METHOD(GoTo, TrackList, SECONDS(1)) |
2796 | + |
2797 | + struct Signals |
2798 | + { |
2799 | + SIGNAL |
2800 | + ( |
2801 | + TrackListReplaced, |
2802 | + TrackList, |
2803 | + BOOST_IDENTITY_TYPE((std::tuple<std::vector<dbus::types::ObjectPath>, dbus::types::ObjectPath>)) |
2804 | + ) |
2805 | + |
2806 | + SIGNAL |
2807 | + ( |
2808 | + TrackAdded, |
2809 | + TrackList, |
2810 | + BOOST_IDENTITY_TYPE((std::tuple<std::map<std::string, dbus::types::Variant<dbus::types::Any>>, dbus::types::ObjectPath>)) |
2811 | + ) |
2812 | + |
2813 | + SIGNAL |
2814 | + ( |
2815 | + TrackRemoved, |
2816 | + TrackList, |
2817 | + dbus::types::ObjectPath |
2818 | + ) |
2819 | + |
2820 | + SIGNAL |
2821 | + ( |
2822 | + TrackMetadataChanged, |
2823 | + TrackList, |
2824 | + BOOST_IDENTITY_TYPE((std::tuple<std::map<std::string, dbus::types::Variant<dbus::types::Any>>, dbus::types::ObjectPath>)) |
2825 | + ) |
2826 | + }; |
2827 | + |
2828 | + struct Properties |
2829 | + { |
2830 | + READABLE_PROPERTY(Tracks, TrackList, std::vector<std::string>) |
2831 | + READABLE_PROPERTY(CanEditTracks, TrackList, bool) |
2832 | + }; |
2833 | +}; |
2834 | +} |
2835 | + |
2836 | +#endif // MPRIS_TRACK_LIST_H_ |
2837 | |
2838 | === added file 'src/com/ubuntu/music/player.cpp' |
2839 | --- src/com/ubuntu/music/player.cpp 1970-01-01 00:00:00 +0000 |
2840 | +++ src/com/ubuntu/music/player.cpp 2013-11-11 13:09:24 +0000 |
2841 | @@ -0,0 +1,39 @@ |
2842 | +/* |
2843 | + * Copyright © 2013 Canonical Ltd. |
2844 | + * |
2845 | + * This program is free software: you can redistribute it and/or modify it |
2846 | + * under the terms of the GNU Lesser General Public License version 3, |
2847 | + * as published by the Free Software Foundation. |
2848 | + * |
2849 | + * This program is distributed in the hope that it will be useful, |
2850 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2851 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2852 | + * GNU Lesser General Public License for more details. |
2853 | + * |
2854 | + * You should have received a copy of the GNU Lesser General Public License |
2855 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2856 | + * |
2857 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2858 | + */ |
2859 | + |
2860 | +#include <com/ubuntu/music/player.h> |
2861 | +#include <com/ubuntu/music/property.h> |
2862 | + |
2863 | +#include "player_configuration.h" |
2864 | + |
2865 | +namespace music = com::ubuntu::music; |
2866 | + |
2867 | +const music::Player::Configuration& music::Player::Client::default_configuration() |
2868 | +{ |
2869 | + static const music::Player::Configuration config; |
2870 | + return config; |
2871 | +} |
2872 | + |
2873 | +music::Player::Player() |
2874 | +{ |
2875 | +} |
2876 | + |
2877 | +music::Player::~Player() |
2878 | +{ |
2879 | +} |
2880 | + |
2881 | |
2882 | === removed file 'src/com/ubuntu/music/player.cpp' |
2883 | --- src/com/ubuntu/music/player.cpp 2013-09-08 11:42:36 +0000 |
2884 | +++ src/com/ubuntu/music/player.cpp 1970-01-01 00:00:00 +0000 |
2885 | @@ -1,192 +0,0 @@ |
2886 | -/* |
2887 | - * Copyright © 2013 Canonical Ltd. |
2888 | - * |
2889 | - * This program is free software: you can redistribute it and/or modify it |
2890 | - * under the terms of the GNU Lesser General Public License version 3, |
2891 | - * as published by the Free Software Foundation. |
2892 | - * |
2893 | - * This program is distributed in the hope that it will be useful, |
2894 | - * but WITHOUT ANY WARRANTY {} without even the implied warranty of |
2895 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2896 | - * GNU Lesser General Public License for more details. |
2897 | - * |
2898 | - * You should have received a copy of the GNU Lesser General Public License |
2899 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2900 | - * |
2901 | - * Authored by: Thomas Voß <thomas.voss@canonical.com> |
2902 | - */ |
2903 | - |
2904 | -#include "com/ubuntu/music/player.h" |
2905 | -#include "com/ubuntu/music/service.h" |
2906 | -#include "com/ubuntu/music/track_list.h" |
2907 | - |
2908 | -#include <limits> |
2909 | - |
2910 | -namespace music = com::ubuntu::music; |
2911 | - |
2912 | -struct music::Player::Private |
2913 | -{ |
2914 | - std::shared_ptr<Service> parent; |
2915 | - std::shared_ptr<TrackList> track_list; |
2916 | -}; |
2917 | - |
2918 | -music::Player::Player(const std::shared_ptr<Service>& parent) : d(new Private{parent, std::make_shared<TrackList>()}) |
2919 | -{ |
2920 | -} |
2921 | - |
2922 | -music::Player::~Player() |
2923 | -{ |
2924 | -} |
2925 | - |
2926 | -const std::shared_ptr<music::TrackList>& music::Player::track_list() const |
2927 | -{ |
2928 | - return d->track_list; |
2929 | -} |
2930 | - |
2931 | -bool music::Player::can_go_next() |
2932 | -{ |
2933 | - return true; |
2934 | -} |
2935 | - |
2936 | -void music::Player::next() |
2937 | -{ |
2938 | -} |
2939 | - |
2940 | -bool music::Player::can_go_previous() |
2941 | -{ |
2942 | - return true; |
2943 | -} |
2944 | - |
2945 | -void music::Player::previous() |
2946 | -{ |
2947 | -} |
2948 | - |
2949 | -bool music::Player::can_play() |
2950 | -{ |
2951 | - return true; |
2952 | -} |
2953 | - |
2954 | -void music::Player::play() |
2955 | -{ |
2956 | -} |
2957 | - |
2958 | -bool music::Player::can_pause() |
2959 | -{ |
2960 | - return true; |
2961 | -} |
2962 | - |
2963 | -void music::Player::pause() |
2964 | -{ |
2965 | -} |
2966 | - |
2967 | -bool music::Player::can_seek() |
2968 | -{ |
2969 | - return true; |
2970 | -} |
2971 | - |
2972 | -void music::Player::seek_to(const std::chrono::microseconds& offset) |
2973 | -{ |
2974 | - (void) offset; |
2975 | -} |
2976 | - |
2977 | -void music::Player::stop() |
2978 | -{ |
2979 | -} |
2980 | - |
2981 | -music::Player::PlaybackStatus music::Player::playback_status() const |
2982 | -{ |
2983 | - return Player::stopped; |
2984 | -} |
2985 | - |
2986 | -music::Connection music::Player::on_playback_status_changed(const std::function<void(music::Player::PlaybackStatus)>& handler) |
2987 | -{ |
2988 | - (void) handler; |
2989 | - return Connection(nullptr); |
2990 | -} |
2991 | - |
2992 | -music::Player::LoopStatus music::Player::loop_status() const |
2993 | -{ |
2994 | - return Player::none; |
2995 | -} |
2996 | - |
2997 | -void music::Player::set_loop_status(music::Player::LoopStatus new_status) |
2998 | -{ |
2999 | - (void) new_status; |
3000 | -} |
3001 | - |
3002 | -music::Connection music::Player::on_loop_status_changed(const std::function<void(music::Player::LoopStatus)>& handler) |
3003 | -{ |
3004 | - (void) handler; |
3005 | - return Connection(nullptr); |
3006 | -} |
3007 | - |
3008 | -music::Player::PlaybackRate music::Player::playback_rate() const |
3009 | -{ |
3010 | - return 1.0; |
3011 | -} |
3012 | - |
3013 | -void music::Player::set_playback_rate(music::Player::PlaybackRate rate) |
3014 | -{ |
3015 | - (void) rate; |
3016 | -} |
3017 | - |
3018 | -music::Connection music::Player::on_playback_rate_changed(const std::function<void(music::Player::PlaybackRate)>& handler) |
3019 | -{ |
3020 | - (void) handler; |
3021 | - |
3022 | - return Connection(nullptr); |
3023 | -} |
3024 | - |
3025 | -bool music::Player::is_shuffle() const |
3026 | -{ |
3027 | - return false; |
3028 | -} |
3029 | - |
3030 | -void music::Player::set_shuffle(bool b) |
3031 | -{ |
3032 | - (void) b; |
3033 | -} |
3034 | - |
3035 | -music::Connection music::Player::on_shuffle_changed(const std::function<void(bool)>& handler) |
3036 | -{ |
3037 | - (void) handler; |
3038 | - return Connection(nullptr); |
3039 | -} |
3040 | - |
3041 | -music::Track::MetaData music::Player::meta_data_for_current_track() const |
3042 | -{ |
3043 | - return Track::MetaData(); |
3044 | -} |
3045 | - |
3046 | -music::Connection music::Player::on_meta_data_for_current_track_changed(const std::function<void(const music::Track::MetaData&)>& handler) |
3047 | -{ |
3048 | - (void) handler; |
3049 | - return Connection(nullptr); |
3050 | -} |
3051 | - |
3052 | -music::Player::Volume music::Player::volume() const |
3053 | -{ |
3054 | - return 0.f; |
3055 | -} |
3056 | - |
3057 | -void music::Player::set_volume(music::Player::Volume new_volume) |
3058 | -{ |
3059 | - (void) new_volume; |
3060 | -} |
3061 | - |
3062 | -music::Connection music::Player::on_volume_changed(const std::function<void(music::Player::Volume)>& handler) |
3063 | -{ |
3064 | - (void) handler; |
3065 | - return Connection(nullptr); |
3066 | -} |
3067 | - |
3068 | -music::Player::PlaybackRate music::Player::minimum_playback_rate() const |
3069 | -{ |
3070 | - return std::numeric_limits<double>::min(); |
3071 | -} |
3072 | - |
3073 | -music::Player::PlaybackRate music::Player::maximum_playback_rate() const |
3074 | -{ |
3075 | - return std::numeric_limits<double>::max(); |
3076 | -} |
3077 | - |
3078 | |
3079 | === added file 'src/com/ubuntu/music/player_configuration.h' |
3080 | --- src/com/ubuntu/music/player_configuration.h 1970-01-01 00:00:00 +0000 |
3081 | +++ src/com/ubuntu/music/player_configuration.h 2013-11-11 13:09:24 +0000 |
3082 | @@ -0,0 +1,30 @@ |
3083 | +/* |
3084 | + * Copyright © 2013 Canonical Ltd. |
3085 | + * |
3086 | + * This program is free software: you can redistribute it and/or modify it |
3087 | + * under the terms of the GNU Lesser General Public License version 3, |
3088 | + * as published by the Free Software Foundation. |
3089 | + * |
3090 | + * This program is distributed in the hope that it will be useful, |
3091 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3092 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3093 | + * GNU Lesser General Public License for more details. |
3094 | + * |
3095 | + * You should have received a copy of the GNU Lesser General Public License |
3096 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3097 | + * |
3098 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3099 | + */ |
3100 | +#ifndef COM_UBUNTU_MUSIC_PLAYER_CLIENT_CONFIGURATION_H_ |
3101 | +#define COM_UBUNTU_MUSIC_PLAYER_CLIENT_CONFIGURATION_H_ |
3102 | + |
3103 | +#include <com/ubuntu/music/player.h> |
3104 | + |
3105 | +#include <org/freedesktop/dbus/types/object_path.h> |
3106 | + |
3107 | +struct com::ubuntu::music::Player::Configuration |
3108 | +{ |
3109 | + org::freedesktop::dbus::types::ObjectPath object_path; |
3110 | +}; |
3111 | + |
3112 | +#endif // COM_UBUNTU_MUSIC_PLAYER_CLIENT_CONFIGURATION_H_ |
3113 | |
3114 | === added file 'src/com/ubuntu/music/player_implementation.cpp' |
3115 | --- src/com/ubuntu/music/player_implementation.cpp 1970-01-01 00:00:00 +0000 |
3116 | +++ src/com/ubuntu/music/player_implementation.cpp 2013-11-11 13:09:24 +0000 |
3117 | @@ -0,0 +1,133 @@ |
3118 | +/* |
3119 | + * |
3120 | + * This program is free software: you can redistribute it and/or modify it |
3121 | + * under the terms of the GNU Lesser General Public License version 3, |
3122 | + * as published by the Free Software Foundation. |
3123 | + * |
3124 | + * This program is distributed in the hope that it will be useful, |
3125 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3126 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3127 | + * GNU Lesser General Public License for more details. |
3128 | + * |
3129 | + * You should have received a copy of the GNU Lesser General Public License |
3130 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3131 | + * |
3132 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3133 | + */ |
3134 | + |
3135 | +#include "player_implementation.h" |
3136 | + |
3137 | +#include "engine.h" |
3138 | +#include "track_list_implementation.h" |
3139 | + |
3140 | +#include <com/ubuntu/music/property.h> |
3141 | + |
3142 | +namespace music = com::ubuntu::music; |
3143 | + |
3144 | +struct music::PlayerImplementation::Private |
3145 | +{ |
3146 | + Private(PlayerImplementation* parent, |
3147 | + const dbus::types::ObjectPath& session_path, |
3148 | + const std::shared_ptr<music::Service>& service, |
3149 | + const std::shared_ptr<music::Engine>& engine) |
3150 | + : parent(parent), |
3151 | + service(service), |
3152 | + engine(engine), |
3153 | + session_path(session_path), |
3154 | + track_list( |
3155 | + new music::TrackListImplementation( |
3156 | + session_path.as_string() + "/TrackList", |
3157 | + engine->meta_data_extractor())) |
3158 | + { |
3159 | + engine->state().changed().connect( |
3160 | + [parent](const Engine::State& state) |
3161 | + { |
3162 | + switch(state) |
3163 | + { |
3164 | + case Engine::State::ready: parent->playback_status().set(music::Player::ready); break; |
3165 | + case Engine::State::playing: parent->playback_status().set(music::Player::playing); break; |
3166 | + case Engine::State::stopped: parent->playback_status().set(music::Player::stopped); break; |
3167 | + case Engine::State::paused: parent->playback_status().set(music::Player::paused); break; |
3168 | + default: |
3169 | + break; |
3170 | + }; |
3171 | + }); |
3172 | + } |
3173 | + |
3174 | + PlayerImplementation* parent; |
3175 | + std::shared_ptr<Service> service; |
3176 | + std::shared_ptr<Engine> engine; |
3177 | + dbus::types::ObjectPath session_path; |
3178 | + std::shared_ptr<TrackListImplementation> track_list; |
3179 | +}; |
3180 | + |
3181 | +music::PlayerImplementation::PlayerImplementation( |
3182 | + const dbus::types::ObjectPath& session_path, |
3183 | + const std::shared_ptr<Service>& service, |
3184 | + const std::shared_ptr<Engine>& engine) |
3185 | + : music::PlayerSkeleton(session_path), |
3186 | + d(new Private( |
3187 | + this, |
3188 | + session_path, |
3189 | + service, |
3190 | + engine)) |
3191 | +{ |
3192 | + // Initializing default values for properties |
3193 | + can_play().set(true); |
3194 | + can_pause().set(true); |
3195 | + can_seek().set(true); |
3196 | + can_go_previous().set(true); |
3197 | + can_go_next().set(true); |
3198 | + is_shuffle().set(true); |
3199 | + playback_rate().set(1.f); |
3200 | + playback_status().set(Player::PlaybackStatus::null); |
3201 | + loop_status().set(Player::LoopStatus::none); |
3202 | +} |
3203 | + |
3204 | +music::PlayerImplementation::~PlayerImplementation() |
3205 | +{ |
3206 | +} |
3207 | + |
3208 | +std::shared_ptr<music::TrackList> music::PlayerImplementation::track_list() |
3209 | +{ |
3210 | + return d->track_list; |
3211 | +} |
3212 | + |
3213 | +bool music::PlayerImplementation::open_uri(const Track::UriType& uri) |
3214 | +{ |
3215 | + std::cout << __PRETTY_FUNCTION__ << ": " << uri << std::endl; |
3216 | + return d->engine->open_resource_for_uri(uri); |
3217 | +} |
3218 | + |
3219 | +void music::PlayerImplementation::next() |
3220 | +{ |
3221 | +} |
3222 | + |
3223 | +void music::PlayerImplementation::previous() |
3224 | +{ |
3225 | +} |
3226 | + |
3227 | +void music::PlayerImplementation::play() |
3228 | +{ |
3229 | + /*if (playback_status() == music::Player::null) |
3230 | + { |
3231 | + if (d->track_list->has_next()) |
3232 | + if (open_uri(d->track_list->next()->)) |
3233 | + }*/ |
3234 | + d->engine->play(); |
3235 | +} |
3236 | + |
3237 | +void music::PlayerImplementation::pause() |
3238 | +{ |
3239 | + d->engine->pause(); |
3240 | +} |
3241 | + |
3242 | +void music::PlayerImplementation::stop() |
3243 | +{ |
3244 | + d->engine->stop(); |
3245 | +} |
3246 | + |
3247 | +void music::PlayerImplementation::seek_to(const std::chrono::microseconds& ms) |
3248 | +{ |
3249 | + d->engine->seek_to(ms); |
3250 | +} |
3251 | |
3252 | === added file 'src/com/ubuntu/music/player_implementation.h' |
3253 | --- src/com/ubuntu/music/player_implementation.h 1970-01-01 00:00:00 +0000 |
3254 | +++ src/com/ubuntu/music/player_implementation.h 2013-11-11 13:09:24 +0000 |
3255 | @@ -0,0 +1,61 @@ |
3256 | +/* |
3257 | + * |
3258 | + * This program is free software: you can redistribute it and/or modify it |
3259 | + * under the terms of the GNU Lesser General Public License version 3, |
3260 | + * as published by the Free Software Foundation. |
3261 | + * |
3262 | + * This program is distributed in the hope that it will be useful, |
3263 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3264 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3265 | + * GNU Lesser General Public License for more details. |
3266 | + * |
3267 | + * You should have received a copy of the GNU Lesser General Public License |
3268 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3269 | + * |
3270 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3271 | + */ |
3272 | + |
3273 | +#ifndef COM_UBUNTU_MUSIC_PLAYER_IMPLEMENTATION_H_ |
3274 | +#define COM_UBUNTU_MUSIC_PLAYER_IMPLEMENTATION_H_ |
3275 | + |
3276 | +#include "player_skeleton.h" |
3277 | + |
3278 | +#include <memory> |
3279 | + |
3280 | +namespace com |
3281 | +{ |
3282 | +namespace ubuntu |
3283 | +{ |
3284 | +namespace music |
3285 | +{ |
3286 | +class Engine; |
3287 | +class Service; |
3288 | + |
3289 | +class PlayerImplementation : public PlayerSkeleton |
3290 | +{ |
3291 | +public: |
3292 | + PlayerImplementation( |
3293 | + const org::freedesktop::dbus::types::ObjectPath& session_path, |
3294 | + const std::shared_ptr<Service>& service, |
3295 | + const std::shared_ptr<Engine>& engine); |
3296 | + ~PlayerImplementation(); |
3297 | + |
3298 | + virtual std::shared_ptr<TrackList> track_list(); |
3299 | + |
3300 | + virtual bool open_uri(const Track::UriType& uri); |
3301 | + virtual void next(); |
3302 | + virtual void previous(); |
3303 | + virtual void play(); |
3304 | + virtual void pause(); |
3305 | + virtual void stop(); |
3306 | + virtual void seek_to(const std::chrono::microseconds& offset); |
3307 | + |
3308 | +private: |
3309 | + struct Private; |
3310 | + std::unique_ptr<Private> d; |
3311 | +}; |
3312 | +} |
3313 | +} |
3314 | +} |
3315 | +#endif // COM_UBUNTU_MUSIC_PLAYER_IMPLEMENTATION_H_ |
3316 | + |
3317 | |
3318 | === added file 'src/com/ubuntu/music/player_skeleton.cpp' |
3319 | --- src/com/ubuntu/music/player_skeleton.cpp 1970-01-01 00:00:00 +0000 |
3320 | +++ src/com/ubuntu/music/player_skeleton.cpp 2013-11-11 13:09:24 +0000 |
3321 | @@ -0,0 +1,325 @@ |
3322 | +/* |
3323 | + * Copyright © 2013 Canonical Ltd. |
3324 | + * |
3325 | + * This program is free software: you can redistribute it and/or modify it |
3326 | + * under the terms of the GNU Lesser General Public License version 3, |
3327 | + * as published by the Free Software Foundation. |
3328 | + * |
3329 | + * This program is distributed in the hope that it will be useful, |
3330 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3331 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3332 | + * GNU Lesser General Public License for more details. |
3333 | + * |
3334 | + * You should have received a copy of the GNU Lesser General Public License |
3335 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3336 | + * |
3337 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3338 | + */ |
3339 | + |
3340 | +#include <com/ubuntu/music/property.h> |
3341 | + |
3342 | +#include "player_skeleton.h" |
3343 | +#include "player_traits.h" |
3344 | +#include "property_stub.h" |
3345 | +#include "the_session_bus.h" |
3346 | + |
3347 | +#include "mpris/player.h" |
3348 | + |
3349 | +#include <org/freedesktop/dbus/stub.h> |
3350 | + |
3351 | +namespace dbus = org::freedesktop::dbus; |
3352 | +namespace music = com::ubuntu::music; |
3353 | + |
3354 | +struct music::PlayerSkeleton::Private |
3355 | +{ |
3356 | + Private(music::PlayerSkeleton* player, const dbus::types::ObjectPath& session) |
3357 | + : impl(player), |
3358 | + object(impl->access_service()->add_object_for_path(session)), |
3359 | + properties |
3360 | + { |
3361 | + object->get_property<mpris::Player::Properties::CanPlay>(), |
3362 | + object->get_property<mpris::Player::Properties::CanPause>(), |
3363 | + object->get_property<mpris::Player::Properties::CanSeek>(), |
3364 | + object->get_property<mpris::Player::Properties::CanControl>(), |
3365 | + object->get_property<mpris::Player::Properties::CanGoNext>(), |
3366 | + object->get_property<mpris::Player::Properties::CanGoPrevious>(), |
3367 | + object->get_property<mpris::Player::Properties::PlaybackStatus>(), |
3368 | + object->get_property<mpris::Player::Properties::LoopStatus>(), |
3369 | + object->get_property<mpris::Player::Properties::PlaybackRate>(), |
3370 | + object->get_property<mpris::Player::Properties::Shuffle>(), |
3371 | + object->get_property<mpris::Player::Properties::MetaData>(), |
3372 | + object->get_property<mpris::Player::Properties::Volume>(), |
3373 | + object->get_property<mpris::Player::Properties::MinimumRate>(), |
3374 | + object->get_property<mpris::Player::Properties::MaximumRate>() |
3375 | + } |
3376 | + { |
3377 | + } |
3378 | + |
3379 | + void handle_next(DBusMessage* msg) |
3380 | + { |
3381 | + impl->next(); |
3382 | + auto reply = dbus::Message::make_method_return(msg); |
3383 | + impl->access_bus()->send(reply->get()); |
3384 | + } |
3385 | + |
3386 | + void handle_previous(DBusMessage* msg) |
3387 | + { |
3388 | + impl->previous(); |
3389 | + auto reply = dbus::Message::make_method_return(msg); |
3390 | + impl->access_bus()->send(reply->get()); |
3391 | + } |
3392 | + |
3393 | + void handle_pause(DBusMessage* msg) |
3394 | + { |
3395 | + impl->pause(); |
3396 | + auto reply = dbus::Message::make_method_return(msg); |
3397 | + impl->access_bus()->send(reply->get()); |
3398 | + } |
3399 | + |
3400 | + void handle_playpause(DBusMessage*) |
3401 | + { |
3402 | + } |
3403 | + |
3404 | + void handle_stop(DBusMessage* msg) |
3405 | + { |
3406 | + impl->stop(); |
3407 | + auto reply = dbus::Message::make_method_return(msg); |
3408 | + impl->access_bus()->send(reply->get()); |
3409 | + } |
3410 | + |
3411 | + void handle_play(DBusMessage* msg) |
3412 | + { |
3413 | + impl->play(); |
3414 | + auto reply = dbus::Message::make_method_return(msg); |
3415 | + impl->access_bus()->send(reply->get()); |
3416 | + } |
3417 | + |
3418 | + void handle_seek(DBusMessage* msg) |
3419 | + { |
3420 | + auto in = dbus::Message::from_raw_message(msg); |
3421 | + uint64_t ticks; |
3422 | + in->reader() >> ticks; |
3423 | + impl->seek_to(std::chrono::microseconds(ticks)); |
3424 | + } |
3425 | + |
3426 | + void handle_set_position(DBusMessage*) |
3427 | + { |
3428 | + } |
3429 | + |
3430 | + void handle_open_uri(DBusMessage* msg) |
3431 | + { |
3432 | + auto in = dbus::Message::from_raw_message(msg); |
3433 | + Track::UriType uri; |
3434 | + in->reader() >> uri; |
3435 | + |
3436 | + auto reply = dbus::Message::make_method_return(msg); |
3437 | + reply->writer() << impl->open_uri(uri); |
3438 | + impl->access_bus()->send(reply->get()); |
3439 | + } |
3440 | + |
3441 | + music::PlayerSkeleton* impl; |
3442 | + dbus::Object::Ptr object; |
3443 | + struct |
3444 | + { |
3445 | + PropertyStub<bool, mpris::Player::Properties::CanPlay> can_play; |
3446 | + PropertyStub<bool, mpris::Player::Properties::CanPause> can_pause; |
3447 | + PropertyStub<bool, mpris::Player::Properties::CanSeek> can_seek; |
3448 | + PropertyStub<bool, mpris::Player::Properties::CanControl> can_control; |
3449 | + PropertyStub<bool, mpris::Player::Properties::CanGoNext> can_go_next; |
3450 | + PropertyStub<bool, mpris::Player::Properties::CanGoPrevious> can_go_previous; |
3451 | + |
3452 | + PropertyStub<Player::PlaybackStatus, mpris::Player::Properties::PlaybackStatus> playback_status; |
3453 | + PropertyStub<Player::LoopStatus, mpris::Player::Properties::LoopStatus> loop_status; |
3454 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::PlaybackRate> playback_rate; |
3455 | + PropertyStub<bool, mpris::Player::Properties::Shuffle> is_shuffle; |
3456 | + PropertyStub<Track::MetaData, mpris::Player::Properties::MetaData> meta_data_for_current_track; |
3457 | + PropertyStub<Player::Volume, mpris::Player::Properties::Volume> volume; |
3458 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::MinimumRate> minimum_playback_rate; |
3459 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::MaximumRate> maximum_playback_rate; |
3460 | + } properties; |
3461 | + |
3462 | + /*struct |
3463 | + { |
3464 | + std::shared_ptr<dbus::Signal<mpris::Player::Signals::Seeked, uint64_t>> seeked; |
3465 | + } signals;*/ |
3466 | + |
3467 | +}; |
3468 | + |
3469 | +music::PlayerSkeleton::PlayerSkeleton( |
3470 | + const org::freedesktop::dbus::types::ObjectPath& session_path) |
3471 | + : dbus::Skeleton<music::Player>(the_session_bus()), |
3472 | + d(new Private{this, session_path}) |
3473 | +{ |
3474 | + d->object->install_method_handler<mpris::Player::Next>( |
3475 | + std::bind(&Private::handle_next, |
3476 | + std::ref(d), |
3477 | + std::placeholders::_1)); |
3478 | + d->object->install_method_handler<mpris::Player::Previous>( |
3479 | + std::bind(&Private::handle_previous, |
3480 | + std::ref(d), |
3481 | + std::placeholders::_1)); |
3482 | + d->object->install_method_handler<mpris::Player::Pause>( |
3483 | + std::bind(&Private::handle_pause, |
3484 | + std::ref(d), |
3485 | + std::placeholders::_1)); |
3486 | + d->object->install_method_handler<mpris::Player::Stop>( |
3487 | + std::bind(&Private::handle_stop, |
3488 | + std::ref(d), |
3489 | + std::placeholders::_1)); |
3490 | + d->object->install_method_handler<mpris::Player::Play>( |
3491 | + std::bind(&Private::handle_play, |
3492 | + std::ref(d), |
3493 | + std::placeholders::_1)); |
3494 | + d->object->install_method_handler<mpris::Player::Seek>( |
3495 | + std::bind(&Private::handle_seek, |
3496 | + std::ref(d), |
3497 | + std::placeholders::_1)); |
3498 | + d->object->install_method_handler<mpris::Player::SetPosition>( |
3499 | + std::bind(&Private::handle_set_position, |
3500 | + std::ref(d), |
3501 | + std::placeholders::_1)); |
3502 | + d->object->install_method_handler<mpris::Player::OpenUri>( |
3503 | + std::bind(&Private::handle_open_uri, |
3504 | + std::ref(d), |
3505 | + std::placeholders::_1)); |
3506 | +} |
3507 | + |
3508 | +music::PlayerSkeleton::~PlayerSkeleton() |
3509 | +{ |
3510 | +} |
3511 | + |
3512 | +const music::Property<bool>& music::PlayerSkeleton::can_play() const |
3513 | +{ |
3514 | + return d->properties.can_play; |
3515 | +} |
3516 | + |
3517 | +const music::Property<bool>& music::PlayerSkeleton::can_pause() const |
3518 | +{ |
3519 | + return d->properties.can_pause; |
3520 | +} |
3521 | + |
3522 | +const music::Property<bool>& music::PlayerSkeleton::can_seek() const |
3523 | +{ |
3524 | + return d->properties.can_seek; |
3525 | +} |
3526 | + |
3527 | +const music::Property<bool>& music::PlayerSkeleton::can_go_previous() const |
3528 | +{ |
3529 | + return d->properties.can_go_previous; |
3530 | +} |
3531 | + |
3532 | +const music::Property<bool>& music::PlayerSkeleton::can_go_next() const |
3533 | +{ |
3534 | + return d->properties.can_go_next; |
3535 | +} |
3536 | + |
3537 | +const music::Property<music::Player::PlaybackStatus>& music::PlayerSkeleton::playback_status() const |
3538 | +{ |
3539 | + return d->properties.playback_status; |
3540 | +} |
3541 | + |
3542 | +const music::Property<music::Player::LoopStatus>& music::PlayerSkeleton::loop_status() const |
3543 | +{ |
3544 | + return d->properties.loop_status; |
3545 | +} |
3546 | + |
3547 | +const music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::playback_rate() const |
3548 | +{ |
3549 | + return d->properties.playback_rate; |
3550 | +} |
3551 | + |
3552 | +const music::Property<bool>& music::PlayerSkeleton::is_shuffle() const |
3553 | +{ |
3554 | + return d->properties.is_shuffle; |
3555 | +} |
3556 | + |
3557 | +const music::Property<music::Track::MetaData>& music::PlayerSkeleton::meta_data_for_current_track() const |
3558 | +{ |
3559 | + return d->properties.meta_data_for_current_track; |
3560 | +} |
3561 | + |
3562 | +const music::Property<music::Player::Volume>& music::PlayerSkeleton::volume() const |
3563 | +{ |
3564 | + return d->properties.volume; |
3565 | +} |
3566 | + |
3567 | +const music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::minimum_playback_rate() const |
3568 | +{ |
3569 | + return d->properties.minimum_playback_rate; |
3570 | +} |
3571 | + |
3572 | +const music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::maximum_playback_rate() const |
3573 | +{ |
3574 | + return d->properties.maximum_playback_rate; |
3575 | +} |
3576 | + |
3577 | +music::Property<music::Player::LoopStatus>& music::PlayerSkeleton::loop_status() |
3578 | +{ |
3579 | + return d->properties.loop_status; |
3580 | +} |
3581 | + |
3582 | +music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::playback_rate() |
3583 | +{ |
3584 | + return d->properties.playback_rate; |
3585 | +} |
3586 | + |
3587 | +music::Property<bool>& music::PlayerSkeleton::is_shuffle() |
3588 | +{ |
3589 | + return d->properties.is_shuffle; |
3590 | +} |
3591 | + |
3592 | +music::Property<music::Player::Volume>& music::PlayerSkeleton::volume() |
3593 | +{ |
3594 | + return d->properties.volume; |
3595 | +} |
3596 | + |
3597 | +music::Property<music::Player::PlaybackStatus>& music::PlayerSkeleton::playback_status() |
3598 | +{ |
3599 | + return d->properties.playback_status; |
3600 | +} |
3601 | + |
3602 | +music::Property<bool>& music::PlayerSkeleton::can_play() |
3603 | +{ |
3604 | + return d->properties.can_play; |
3605 | +} |
3606 | + |
3607 | +music::Property<bool>& music::PlayerSkeleton::can_pause() |
3608 | +{ |
3609 | + return d->properties.can_pause; |
3610 | +} |
3611 | + |
3612 | +music::Property<bool>& music::PlayerSkeleton::can_seek() |
3613 | +{ |
3614 | + return d->properties.can_seek; |
3615 | +} |
3616 | + |
3617 | +music::Property<bool>& music::PlayerSkeleton::can_go_previous() |
3618 | +{ |
3619 | + return d->properties.can_go_previous; |
3620 | +} |
3621 | + |
3622 | +music::Property<bool>& music::PlayerSkeleton::can_go_next() |
3623 | +{ |
3624 | + return d->properties.can_go_next; |
3625 | +} |
3626 | + |
3627 | +music::Property<music::Track::MetaData>& music::PlayerSkeleton::meta_data_for_current_track() |
3628 | +{ |
3629 | + return d->properties.meta_data_for_current_track; |
3630 | +} |
3631 | + |
3632 | +music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::minimum_playback_rate() |
3633 | +{ |
3634 | + return d->properties.minimum_playback_rate; |
3635 | +} |
3636 | + |
3637 | +music::Property<music::Player::PlaybackRate>& music::PlayerSkeleton::maximum_playback_rate() |
3638 | +{ |
3639 | + return d->properties.maximum_playback_rate; |
3640 | +} |
3641 | + |
3642 | +const music::Signal<uint64_t>& music::PlayerSkeleton::seeked_to() const |
3643 | +{ |
3644 | + static const music::Signal<uint64_t> signal; |
3645 | + return signal; |
3646 | +} |
3647 | |
3648 | === added file 'src/com/ubuntu/music/player_skeleton.h' |
3649 | --- src/com/ubuntu/music/player_skeleton.h 1970-01-01 00:00:00 +0000 |
3650 | +++ src/com/ubuntu/music/player_skeleton.h 2013-11-11 13:09:24 +0000 |
3651 | @@ -0,0 +1,86 @@ |
3652 | +/** |
3653 | + * This program is free software: you can redistribute it and/or modify it |
3654 | + * under the terms of the GNU Lesser General Public License version 3, |
3655 | + * as published by the Free Software Foundation. |
3656 | + * |
3657 | + * This program is distributed in the hope that it will be useful, |
3658 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3659 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3660 | + * GNU Lesser General Public License for more details. |
3661 | + * |
3662 | + * You should have received a copy of the GNU Lesser General Public License |
3663 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3664 | + * |
3665 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3666 | + */ |
3667 | + |
3668 | +#ifndef COM_UBUNTU_MUSIC_PLAYER_SKELETON_H_ |
3669 | +#define COM_UBUNTU_MUSIC_PLAYER_SKELETON_H_ |
3670 | + |
3671 | +#include <com/ubuntu/music/player.h> |
3672 | + |
3673 | +#include "player_traits.h" |
3674 | + |
3675 | +#include "mpris/player.h" |
3676 | + |
3677 | +#include <org/freedesktop/dbus/skeleton.h> |
3678 | +#include <org/freedesktop/dbus/types/object_path.h> |
3679 | + |
3680 | +#include <memory> |
3681 | + |
3682 | +namespace com |
3683 | +{ |
3684 | +namespace ubuntu |
3685 | +{ |
3686 | +namespace music |
3687 | +{ |
3688 | +class Service; |
3689 | + |
3690 | +class PlayerSkeleton : public org::freedesktop::dbus::Skeleton<com::ubuntu::music::Player> |
3691 | +{ |
3692 | + public: |
3693 | + ~PlayerSkeleton(); |
3694 | + |
3695 | + virtual const Property<bool>& can_play() const; |
3696 | + virtual const Property<bool>& can_pause() const; |
3697 | + virtual const Property<bool>& can_seek() const; |
3698 | + virtual const Property<bool>& can_go_previous() const; |
3699 | + virtual const Property<bool>& can_go_next() const; |
3700 | + virtual const Property<PlaybackStatus>& playback_status() const; |
3701 | + virtual const Property<LoopStatus>& loop_status() const; |
3702 | + virtual const Property<PlaybackRate>& playback_rate() const; |
3703 | + virtual const Property<bool>& is_shuffle() const; |
3704 | + virtual const Property<Track::MetaData>& meta_data_for_current_track() const; |
3705 | + virtual const Property<Volume>& volume() const; |
3706 | + virtual const Property<PlaybackRate>& minimum_playback_rate() const; |
3707 | + virtual const Property<PlaybackRate>& maximum_playback_rate() const; |
3708 | + |
3709 | + virtual Property<LoopStatus>& loop_status(); |
3710 | + virtual Property<PlaybackRate>& playback_rate(); |
3711 | + virtual Property<bool>& is_shuffle(); |
3712 | + virtual Property<Volume>& volume(); |
3713 | + |
3714 | + virtual const Signal<uint64_t>& seeked_to() const; |
3715 | + |
3716 | + protected: |
3717 | + PlayerSkeleton(const org::freedesktop::dbus::types::ObjectPath& session_path); |
3718 | + |
3719 | + virtual Property<PlaybackStatus>& playback_status(); |
3720 | + virtual Property<bool>& can_play(); |
3721 | + virtual Property<bool>& can_pause(); |
3722 | + virtual Property<bool>& can_seek(); |
3723 | + virtual Property<bool>& can_go_previous(); |
3724 | + virtual Property<bool>& can_go_next(); |
3725 | + virtual Property<Track::MetaData>& meta_data_for_current_track(); |
3726 | + virtual Property<PlaybackRate>& minimum_playback_rate(); |
3727 | + virtual Property<PlaybackRate>& maximum_playback_rate(); |
3728 | + |
3729 | + private: |
3730 | + struct Private; |
3731 | + std::unique_ptr<Private> d; |
3732 | +}; |
3733 | +} |
3734 | +} |
3735 | +} |
3736 | + |
3737 | +#endif // COM_UBUNTU_MUSIC_PLAYER_SKELETON_H_ |
3738 | |
3739 | === added file 'src/com/ubuntu/music/player_stub.cpp' |
3740 | --- src/com/ubuntu/music/player_stub.cpp 1970-01-01 00:00:00 +0000 |
3741 | +++ src/com/ubuntu/music/player_stub.cpp 2013-11-11 13:09:24 +0000 |
3742 | @@ -0,0 +1,260 @@ |
3743 | +/* |
3744 | + * Copyright © 2013 Canonical Ltd. |
3745 | + * |
3746 | + * This program is free software: you can redistribute it and/or modify it |
3747 | + * under the terms of the GNU Lesser General Public License version 3, |
3748 | + * as published by the Free Software Foundation. |
3749 | + * |
3750 | + * This program is distributed in the hope that it will be useful, |
3751 | + * but WITHOUT ANY WARRANTY {} without even the implied warranty of |
3752 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3753 | + * GNU Lesser General Public License for more details. |
3754 | + * |
3755 | + * You should have received a copy of the GNU Lesser General Public License |
3756 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3757 | + * |
3758 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
3759 | + */ |
3760 | + |
3761 | +#include <com/ubuntu/music/property.h> |
3762 | +#include <com/ubuntu/music/service.h> |
3763 | +#include <com/ubuntu/music/track_list.h> |
3764 | + |
3765 | +#include "player_stub.h" |
3766 | +#include "player_traits.h" |
3767 | +#include "property_stub.h" |
3768 | +#include "the_session_bus.h" |
3769 | +#include "track_list_stub.h" |
3770 | + |
3771 | +#include "mpris/player.h" |
3772 | + |
3773 | +#include <org/freedesktop/dbus/types/object_path.h> |
3774 | + |
3775 | +#include <limits> |
3776 | + |
3777 | +namespace dbus = org::freedesktop::dbus; |
3778 | +namespace music = com::ubuntu::music; |
3779 | + |
3780 | +struct music::PlayerStub::Private |
3781 | +{ |
3782 | + Private(const std::shared_ptr<Service>& parent, |
3783 | + const std::shared_ptr<dbus::Service>& remote, |
3784 | + const dbus::types::ObjectPath& path |
3785 | + ) : parent(parent), |
3786 | + path(path), |
3787 | + object(remote->object_for_path(path)), |
3788 | + properties |
3789 | + { |
3790 | + object->get_property<mpris::Player::Properties::CanPlay>(), |
3791 | + object->get_property<mpris::Player::Properties::CanPause>(), |
3792 | + object->get_property<mpris::Player::Properties::CanSeek>(), |
3793 | + object->get_property<mpris::Player::Properties::CanControl>(), |
3794 | + object->get_property<mpris::Player::Properties::CanGoNext>(), |
3795 | + object->get_property<mpris::Player::Properties::CanGoPrevious>(), |
3796 | + object->get_property<mpris::Player::Properties::PlaybackStatus>(), |
3797 | + object->get_property<mpris::Player::Properties::LoopStatus>(), |
3798 | + object->get_property<mpris::Player::Properties::PlaybackRate>(), |
3799 | + object->get_property<mpris::Player::Properties::Shuffle>(), |
3800 | + object->get_property<mpris::Player::Properties::MetaData>(), |
3801 | + object->get_property<mpris::Player::Properties::Volume>(), |
3802 | + object->get_property<mpris::Player::Properties::MinimumRate>(), |
3803 | + object->get_property<mpris::Player::Properties::MaximumRate>() |
3804 | + } |
3805 | + { |
3806 | + } |
3807 | + |
3808 | + std::shared_ptr<Service> parent; |
3809 | + std::shared_ptr<TrackList> track_list; |
3810 | + |
3811 | + dbus::Bus::Ptr bus; |
3812 | + dbus::types::ObjectPath path; |
3813 | + dbus::Object::Ptr object; |
3814 | + |
3815 | + struct |
3816 | + { |
3817 | + PropertyStub<bool, mpris::Player::Properties::CanPlay> can_play; |
3818 | + PropertyStub<bool, mpris::Player::Properties::CanPause> can_pause; |
3819 | + PropertyStub<bool, mpris::Player::Properties::CanSeek> can_seek; |
3820 | + PropertyStub<bool, mpris::Player::Properties::CanControl> can_control; |
3821 | + PropertyStub<bool, mpris::Player::Properties::CanGoNext> can_go_next; |
3822 | + PropertyStub<bool, mpris::Player::Properties::CanGoPrevious> can_go_previous; |
3823 | + |
3824 | + PropertyStub<Player::PlaybackStatus, mpris::Player::Properties::PlaybackStatus> playback_status; |
3825 | + PropertyStub<Player::LoopStatus, mpris::Player::Properties::LoopStatus> loop_status; |
3826 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::PlaybackRate> playback_rate; |
3827 | + PropertyStub<bool, mpris::Player::Properties::Shuffle> is_shuffle; |
3828 | + PropertyStub<Track::MetaData, mpris::Player::Properties::MetaData> meta_data_for_current_track; |
3829 | + PropertyStub<Player::Volume, mpris::Player::Properties::Volume> volume; |
3830 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::MinimumRate> minimum_playback_rate; |
3831 | + PropertyStub<Player::PlaybackRate, mpris::Player::Properties::MaximumRate> maximum_playback_rate; |
3832 | + } properties; |
3833 | +}; |
3834 | + |
3835 | +music::PlayerStub::PlayerStub( |
3836 | + const std::shared_ptr<Service>& parent, |
3837 | + const dbus::types::ObjectPath& object_path) |
3838 | + : dbus::Stub<Player>(the_session_bus()), |
3839 | + d(new Private{parent, access_service(), object_path}) |
3840 | +{ |
3841 | +} |
3842 | + |
3843 | +music::PlayerStub::~PlayerStub() |
3844 | +{ |
3845 | +} |
3846 | + |
3847 | +std::shared_ptr<music::TrackList> music::PlayerStub::track_list() |
3848 | +{ |
3849 | + if (!d->track_list) |
3850 | + { |
3851 | + d->track_list = std::make_shared<music::TrackListStub>( |
3852 | + shared_from_this(), |
3853 | + dbus::types::ObjectPath(d->path.as_string() + "/TrackList")); |
3854 | + } |
3855 | + return d->track_list; |
3856 | +} |
3857 | + |
3858 | +bool music::PlayerStub::open_uri(const music::Track::UriType& uri) |
3859 | +{ |
3860 | + auto op = d->object->invoke_method_synchronously<mpris::Player::OpenUri, music::Track::UriType>(uri); |
3861 | + |
3862 | + return op.is_error(); |
3863 | +} |
3864 | + |
3865 | +void music::PlayerStub::next() |
3866 | +{ |
3867 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Next, void>(); |
3868 | + |
3869 | + if (op.is_error()) |
3870 | + throw std::runtime_error("Problem switching to next track on remote object"); |
3871 | +} |
3872 | + |
3873 | +void music::PlayerStub::previous() |
3874 | +{ |
3875 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Previous, void>(); |
3876 | + |
3877 | + if (op.is_error()) |
3878 | + throw std::runtime_error("Problem switching to previous track on remote object"); |
3879 | +} |
3880 | + |
3881 | +void music::PlayerStub::play() |
3882 | +{ |
3883 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Play, void>(); |
3884 | + |
3885 | + if (op.is_error()) |
3886 | + throw std::runtime_error("Problem starting playback on remote object"); |
3887 | +} |
3888 | + |
3889 | +void music::PlayerStub::pause() |
3890 | +{ |
3891 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Pause, void>(); |
3892 | + |
3893 | + if (op.is_error()) |
3894 | + throw std::runtime_error("Problem pausing playback on remote object"); |
3895 | +} |
3896 | + |
3897 | +void music::PlayerStub::seek_to(const std::chrono::microseconds& offset) |
3898 | +{ |
3899 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Seek, void, uint64_t>(offset.count()); |
3900 | + |
3901 | + if (op.is_error()) |
3902 | + throw std::runtime_error("Problem seeking on remote object"); |
3903 | +} |
3904 | + |
3905 | +void music::PlayerStub::stop() |
3906 | +{ |
3907 | + auto op = d->object->invoke_method_synchronously<mpris::Player::Stop, void>(); |
3908 | + |
3909 | + if (op.is_error()) |
3910 | + throw std::runtime_error("Problem stopping playback on remote object"); |
3911 | +} |
3912 | + |
3913 | +const music::Property<bool>& music::PlayerStub::can_play() const |
3914 | +{ |
3915 | + return d->properties.can_play; |
3916 | +} |
3917 | + |
3918 | +const music::Property<bool>& music::PlayerStub::can_pause() const |
3919 | +{ |
3920 | + return d->properties.can_pause; |
3921 | +} |
3922 | + |
3923 | +const music::Property<bool>& music::PlayerStub::can_seek() const |
3924 | +{ |
3925 | + return d->properties.can_seek; |
3926 | +} |
3927 | + |
3928 | +const music::Property<bool>& music::PlayerStub::can_go_previous() const |
3929 | +{ |
3930 | + return d->properties.can_go_previous; |
3931 | +} |
3932 | + |
3933 | +const music::Property<bool>& music::PlayerStub::can_go_next() const |
3934 | +{ |
3935 | + return d->properties.can_go_next; |
3936 | +} |
3937 | + |
3938 | +const music::Property<music::Player::PlaybackStatus>& music::PlayerStub::playback_status() const |
3939 | +{ |
3940 | + return d->properties.playback_status; |
3941 | +} |
3942 | + |
3943 | +const music::Property<music::Player::LoopStatus>& music::PlayerStub::loop_status() const |
3944 | +{ |
3945 | + return d->properties.loop_status; |
3946 | +} |
3947 | + |
3948 | +const music::Property<music::Player::PlaybackRate>& music::PlayerStub::playback_rate() const |
3949 | +{ |
3950 | + return d->properties.playback_rate; |
3951 | +} |
3952 | + |
3953 | +const music::Property<bool>& music::PlayerStub::is_shuffle() const |
3954 | +{ |
3955 | + return d->properties.is_shuffle; |
3956 | +} |
3957 | + |
3958 | +const music::Property<music::Track::MetaData>& music::PlayerStub::meta_data_for_current_track() const |
3959 | +{ |
3960 | + return d->properties.meta_data_for_current_track; |
3961 | +} |
3962 | + |
3963 | +const music::Property<music::Player::Volume>& music::PlayerStub::volume() const |
3964 | +{ |
3965 | + return d->properties.volume; |
3966 | +} |
3967 | + |
3968 | +const music::Property<music::Player::PlaybackRate>& music::PlayerStub::minimum_playback_rate() const |
3969 | +{ |
3970 | + return d->properties.minimum_playback_rate; |
3971 | +} |
3972 | + |
3973 | +const music::Property<music::Player::PlaybackRate>& music::PlayerStub::maximum_playback_rate() const |
3974 | +{ |
3975 | + return d->properties.maximum_playback_rate; |
3976 | +} |
3977 | + |
3978 | +music::Property<music::Player::LoopStatus>& music::PlayerStub::loop_status() |
3979 | +{ |
3980 | + return d->properties.loop_status; |
3981 | +} |
3982 | + |
3983 | +music::Property<music::Player::PlaybackRate>& music::PlayerStub::playback_rate() |
3984 | +{ |
3985 | + return d->properties.playback_rate; |
3986 | +} |
3987 | + |
3988 | +music::Property<bool>& music::PlayerStub::is_shuffle() |
3989 | +{ |
3990 | + return d->properties.is_shuffle; |
3991 | +} |
3992 | + |
3993 | +music::Property<music::Player::Volume>& music::PlayerStub::volume() |
3994 | +{ |
3995 | + return d->properties.volume; |
3996 | +} |
3997 | + |
3998 | +const music::Signal<uint64_t>& music::PlayerStub::seeked_to() const |
3999 | +{ |
4000 | + static music::Signal<uint64_t> signal; |
4001 | + return signal; |
4002 | +} |
4003 | |
4004 | === added file 'src/com/ubuntu/music/player_stub.h' |
4005 | --- src/com/ubuntu/music/player_stub.h 1970-01-01 00:00:00 +0000 |
4006 | +++ src/com/ubuntu/music/player_stub.h 2013-11-11 13:09:24 +0000 |
4007 | @@ -0,0 +1,84 @@ |
4008 | +/* |
4009 | + * Copyright © 2013 Canonical Ltd. |
4010 | + * |
4011 | + * This program is free software: you can redistribute it and/or modify it |
4012 | + * under the terms of the GNU Lesser General Public License version 3, |
4013 | + * as published by the Free Software Foundation. |
4014 | + * |
4015 | + * This program is distributed in the hope that it will be useful, |
4016 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4017 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4018 | + * GNU Lesser General Public License for more details. |
4019 | + * |
4020 | + * You should have received a copy of the GNU Lesser General Public License |
4021 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4022 | + * |
4023 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4024 | + */ |
4025 | + |
4026 | +#ifndef COM_UBUNTU_MUSIC_PLAYER_STUB_H_ |
4027 | +#define COM_UBUNTU_MUSIC_PLAYER_STUB_H_ |
4028 | + |
4029 | +#include <com/ubuntu/music/player.h> |
4030 | + |
4031 | +#include <org/freedesktop/dbus/stub.h> |
4032 | + |
4033 | +#include <memory> |
4034 | + |
4035 | +namespace com |
4036 | +{ |
4037 | +namespace ubuntu |
4038 | +{ |
4039 | +namespace music |
4040 | +{ |
4041 | +class Service; |
4042 | + |
4043 | +class PlayerStub : public org::freedesktop::dbus::Stub<Player> |
4044 | +{ |
4045 | + public: |
4046 | + explicit PlayerStub( |
4047 | + const std::shared_ptr<Service>& parent, |
4048 | + const org::freedesktop::dbus::types::ObjectPath& object); |
4049 | + |
4050 | + ~PlayerStub(); |
4051 | + |
4052 | + virtual std::shared_ptr<TrackList> track_list(); |
4053 | + |
4054 | + virtual bool open_uri(const Track::UriType& uri); |
4055 | + virtual void next(); |
4056 | + virtual void previous(); |
4057 | + virtual void play(); |
4058 | + virtual void pause(); |
4059 | + virtual void seek_to(const std::chrono::microseconds& offset); |
4060 | + virtual void stop(); |
4061 | + |
4062 | + virtual const Property<bool>& can_play() const; |
4063 | + virtual const Property<bool>& can_pause() const; |
4064 | + virtual const Property<bool>& can_seek() const; |
4065 | + virtual const Property<bool>& can_go_previous() const; |
4066 | + virtual const Property<bool>& can_go_next() const; |
4067 | + virtual const Property<PlaybackStatus>& playback_status() const; |
4068 | + virtual const Property<LoopStatus>& loop_status() const; |
4069 | + virtual const Property<PlaybackRate>& playback_rate() const; |
4070 | + virtual const Property<bool>& is_shuffle() const; |
4071 | + virtual const Property<Track::MetaData>& meta_data_for_current_track() const; |
4072 | + virtual const Property<Volume>& volume() const; |
4073 | + virtual const Property<PlaybackRate>& minimum_playback_rate() const; |
4074 | + virtual const Property<PlaybackRate>& maximum_playback_rate() const; |
4075 | + |
4076 | + virtual Property<LoopStatus>& loop_status(); |
4077 | + virtual Property<PlaybackRate>& playback_rate(); |
4078 | + virtual Property<bool>& is_shuffle(); |
4079 | + virtual Property<Volume>& volume(); |
4080 | + |
4081 | + virtual const Signal<uint64_t>& seeked_to() const; |
4082 | + |
4083 | + private: |
4084 | + struct Private; |
4085 | + std::unique_ptr<Private> d; |
4086 | +}; |
4087 | +} |
4088 | +} |
4089 | +} |
4090 | + |
4091 | +#endif // COM_UBUNTU_MUSIC_PLAYER_STUB_H_ |
4092 | |
4093 | === added file 'src/com/ubuntu/music/player_traits.h' |
4094 | --- src/com/ubuntu/music/player_traits.h 1970-01-01 00:00:00 +0000 |
4095 | +++ src/com/ubuntu/music/player_traits.h 2013-11-11 13:09:24 +0000 |
4096 | @@ -0,0 +1,50 @@ |
4097 | +/* |
4098 | + * Copyright © 2013 Canonical Ltd. |
4099 | + * |
4100 | + * This program is free software: you can redistribute it and/or modify it |
4101 | + * under the terms of the GNU Lesser General Public License version 3, |
4102 | + * as published by the Free Software Foundation. |
4103 | + * |
4104 | + * This program is distributed in the hope that it will be useful, |
4105 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4106 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4107 | + * GNU Lesser General Public License for more details. |
4108 | + * |
4109 | + * You should have received a copy of the GNU Lesser General Public License |
4110 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4111 | + * |
4112 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4113 | + */ |
4114 | + |
4115 | +#ifndef PLAYER_TRAITS_H_ |
4116 | +#define PLAYER_TRAITS_H_ |
4117 | + |
4118 | +#include <org/freedesktop/dbus/traits/service.h> |
4119 | + |
4120 | +namespace org |
4121 | +{ |
4122 | +namespace freedesktop |
4123 | +{ |
4124 | +namespace dbus |
4125 | +{ |
4126 | +namespace traits |
4127 | +{ |
4128 | +template<> |
4129 | +struct Service<com::ubuntu::music::Player> |
4130 | +{ |
4131 | + static const std::string& interface_name() |
4132 | + { |
4133 | + static const std::string s |
4134 | + { |
4135 | + "com.ubuntu.music.Service.Player" |
4136 | + }; |
4137 | + return s; |
4138 | + } |
4139 | +}; |
4140 | +} |
4141 | +} |
4142 | +} |
4143 | +} |
4144 | + |
4145 | + |
4146 | +#endif // PLAYER_TRAITS_H_ |
4147 | |
4148 | === added file 'src/com/ubuntu/music/property_stub.h' |
4149 | --- src/com/ubuntu/music/property_stub.h 1970-01-01 00:00:00 +0000 |
4150 | +++ src/com/ubuntu/music/property_stub.h 2013-11-11 13:09:24 +0000 |
4151 | @@ -0,0 +1,244 @@ |
4152 | +/* |
4153 | + * Copyright © 2013 Canonical Ltd. |
4154 | + * |
4155 | + * This program is free software: you can redistribute it and/or modify it |
4156 | + * under the terms of the GNU Lesser General Public License version 3, |
4157 | + * as published by the Free Software Foundation. |
4158 | + * |
4159 | + * This program is distributed in the hope that it will be useful, |
4160 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4161 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4162 | + * GNU Lesser General Public License for more details. |
4163 | + * |
4164 | + * You should have received a copy of the GNU Lesser General Public License |
4165 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4166 | + * |
4167 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4168 | + */ |
4169 | + |
4170 | +#ifndef COM_UBUNTU_MUSIC_PROPERTY_STUB_H_ |
4171 | +#define COM_UBUNTU_MUSIC_PROPERTY_STUB_H_ |
4172 | + |
4173 | +#include <com/ubuntu/music/player.h> |
4174 | +#include <com/ubuntu/music/property.h> |
4175 | +#include <com/ubuntu/music/track_list.h> |
4176 | + |
4177 | +#include <org/freedesktop/dbus/service.h> |
4178 | +#include <org/freedesktop/dbus/types/stl/vector.h> |
4179 | + |
4180 | +#include "mpris/player.h" |
4181 | +#include "mpris/track_list.h" |
4182 | + |
4183 | +namespace com |
4184 | +{ |
4185 | +namespace ubuntu |
4186 | +{ |
4187 | +namespace music |
4188 | +{ |
4189 | + |
4190 | +template<typename T, typename DBusProperty> |
4191 | +struct PropertyStub : public Property<T> |
4192 | +{ |
4193 | + typedef music::Property<T> super; |
4194 | + |
4195 | + PropertyStub(const std::shared_ptr<org::freedesktop::dbus::Property<DBusProperty>>& dbus_property) |
4196 | + : super(), |
4197 | + dbus_property(dbus_property) |
4198 | + { |
4199 | + } |
4200 | + |
4201 | + const T& get() const |
4202 | + { |
4203 | + super::mutable_get() = dbus_property->value(); |
4204 | + return super::get(); |
4205 | + } |
4206 | + |
4207 | + void set(const T& value) |
4208 | + { |
4209 | + dbus_property->value(value); |
4210 | + super::set(value); |
4211 | + } |
4212 | + |
4213 | + std::shared_ptr<org::freedesktop::dbus::Property<DBusProperty>> dbus_property; |
4214 | +}; |
4215 | + |
4216 | +template<> |
4217 | +struct PropertyStub<music::Player::PlaybackStatus, mpris::Player::Properties::PlaybackStatus> : public music::Property<music::Player::PlaybackStatus> |
4218 | +{ |
4219 | + typedef music::Property<Player::PlaybackStatus> super; |
4220 | + |
4221 | + static const std::map<Player::PlaybackStatus, std::string>& playback_status_lut() |
4222 | + { |
4223 | + static const std::map<Player::PlaybackStatus, std::string> lut = |
4224 | + { |
4225 | + {Player::PlaybackStatus::null, "null"}, |
4226 | + {Player::PlaybackStatus::ready, "ready"}, |
4227 | + {Player::PlaybackStatus::playing, "playing"}, |
4228 | + {Player::PlaybackStatus::paused, "paused"}, |
4229 | + {Player::PlaybackStatus::stopped, "stopped"} |
4230 | + }; |
4231 | + |
4232 | + return lut; |
4233 | + } |
4234 | + |
4235 | + static const std::map<std::string, Player::PlaybackStatus>& reverse_playback_status_lut() |
4236 | + { |
4237 | + static const std::map<std::string, Player::PlaybackStatus> lut = |
4238 | + { |
4239 | + {"null", Player::PlaybackStatus::null}, |
4240 | + {"ready", Player::PlaybackStatus::ready}, |
4241 | + {"playing", Player::PlaybackStatus::playing}, |
4242 | + {"paused", Player::PlaybackStatus::paused}, |
4243 | + {"stopped", Player::PlaybackStatus::stopped} |
4244 | + }; |
4245 | + |
4246 | + return lut; |
4247 | + } |
4248 | + |
4249 | + PropertyStub(const std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::PlaybackStatus>>& dbus_property) |
4250 | + : super(), |
4251 | + dbus_property(dbus_property) |
4252 | + { |
4253 | + } |
4254 | + |
4255 | + const Player::PlaybackStatus& get() const |
4256 | + { |
4257 | + auto value = dbus_property->value(); |
4258 | + super::mutable_get() = reverse_playback_status_lut().at(value); |
4259 | + return super::get(); |
4260 | + } |
4261 | + |
4262 | + void set(const Player::PlaybackStatus& value) |
4263 | + { |
4264 | + dbus_property->value(playback_status_lut().at(value)); |
4265 | + super::set(value); |
4266 | + } |
4267 | + |
4268 | + std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::PlaybackStatus>> dbus_property; |
4269 | +}; |
4270 | + |
4271 | +template<> |
4272 | +struct PropertyStub<Player::LoopStatus, mpris::Player::Properties::LoopStatus> |
4273 | + : public Property<Player::LoopStatus> |
4274 | +{ |
4275 | + typedef Property<Player::LoopStatus> super; |
4276 | + |
4277 | + static const std::map<Player::LoopStatus, std::string>& loop_status_lut() |
4278 | + { |
4279 | + static const std::map<Player::LoopStatus, std::string> lut = |
4280 | + { |
4281 | + {Player::LoopStatus::none, "none"}, |
4282 | + {Player::LoopStatus::track, "track"}, |
4283 | + {Player::LoopStatus::playlist, "playlist"} |
4284 | + }; |
4285 | + |
4286 | + return lut; |
4287 | + } |
4288 | + |
4289 | + static const std::map<std::string, Player::LoopStatus>& reverse_loop_status_lut() |
4290 | + { |
4291 | + static const std::map<std::string, Player::LoopStatus> lut = |
4292 | + { |
4293 | + {"none", Player::LoopStatus::none}, |
4294 | + {"track", Player::LoopStatus::track}, |
4295 | + {"playlist", Player::LoopStatus::playlist} |
4296 | + }; |
4297 | + |
4298 | + return lut; |
4299 | + } |
4300 | + |
4301 | + PropertyStub( |
4302 | + const std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::LoopStatus>>& dbus_property) |
4303 | + : super(), |
4304 | + dbus_property(dbus_property) |
4305 | + { |
4306 | + } |
4307 | + |
4308 | + const Player::LoopStatus& get() const |
4309 | + { |
4310 | + auto value = dbus_property->value(); |
4311 | + super::mutable_get() = reverse_loop_status_lut().at(value); |
4312 | + return super::get(); |
4313 | + } |
4314 | + |
4315 | + void set(const Player::LoopStatus& value) |
4316 | + { |
4317 | + dbus_property->value(loop_status_lut().at(value)); |
4318 | + super::set(value); |
4319 | + } |
4320 | + |
4321 | + std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::LoopStatus>> dbus_property; |
4322 | +}; |
4323 | + |
4324 | +template<> |
4325 | +struct PropertyStub<TrackList::Container, mpris::TrackList::Properties::Tracks> |
4326 | + : public Property<TrackList::Container> |
4327 | +{ |
4328 | + typedef Property<TrackList::Container> super; |
4329 | + |
4330 | + PropertyStub( |
4331 | + const std::shared_ptr<org::freedesktop::dbus::Property<mpris::TrackList::Properties::Tracks>>& dbus_property) |
4332 | + : super(), |
4333 | + dbus_property(dbus_property) |
4334 | + { |
4335 | + } |
4336 | + |
4337 | + const TrackList::Container& get() const |
4338 | + { |
4339 | + auto remote_value = dbus_property->value(); |
4340 | + |
4341 | + super::mutable_get().clear(); |
4342 | + for (auto path : remote_value) |
4343 | + { |
4344 | + super::mutable_get().push_back( |
4345 | + music::Track::Id{path}); |
4346 | + } |
4347 | + return super::get(); |
4348 | + } |
4349 | + |
4350 | + void set(const TrackList::Container& value) |
4351 | + { |
4352 | + mpris::TrackList::Properties::Tracks::ValueType dbus_tracks; |
4353 | + |
4354 | + for (auto track : value) |
4355 | + { |
4356 | + dbus_tracks.push_back(track); |
4357 | + } |
4358 | + |
4359 | + dbus_property->value(dbus_tracks); |
4360 | + |
4361 | + super::set(value); |
4362 | + } |
4363 | + |
4364 | + std::shared_ptr<org::freedesktop::dbus::Property<mpris::TrackList::Properties::Tracks>> dbus_property; |
4365 | +}; |
4366 | + |
4367 | +template<> |
4368 | +struct PropertyStub<Track::MetaData, mpris::Player::Properties::MetaData> |
4369 | + : public Property<Track::MetaData> |
4370 | +{ |
4371 | + typedef Property<Track::MetaData> super; |
4372 | + |
4373 | + PropertyStub( |
4374 | + const std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::MetaData>>& dbus_property) |
4375 | + : super(), |
4376 | + dbus_property(dbus_property) |
4377 | + { |
4378 | + } |
4379 | + |
4380 | + const Track::MetaData& get() const |
4381 | + { |
4382 | + return super::get(); |
4383 | + } |
4384 | + |
4385 | + void set(const Track::MetaData& value) |
4386 | + { |
4387 | + super::set(value); |
4388 | + } |
4389 | + |
4390 | + std::shared_ptr<org::freedesktop::dbus::Property<mpris::Player::Properties::MetaData>> dbus_property; |
4391 | +}; |
4392 | +} |
4393 | +} |
4394 | +} |
4395 | +#endif // COM_UBUNTU_MUSIC_PROPERTY_STUB_H_ |
4396 | |
4397 | === modified file 'src/com/ubuntu/music/service.cpp' |
4398 | --- src/com/ubuntu/music/service.cpp 2013-09-03 18:44:05 +0000 |
4399 | +++ src/com/ubuntu/music/service.cpp 2013-11-11 13:09:24 +0000 |
4400 | @@ -16,27 +16,14 @@ |
4401 | * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4402 | */ |
4403 | |
4404 | -#include "com/ubuntu/music/player.h" |
4405 | -#include "com/ubuntu/music/service.h" |
4406 | +#include <com/ubuntu/music/service.h> |
4407 | + |
4408 | +#include "service_stub.h" |
4409 | |
4410 | namespace music = com::ubuntu::music; |
4411 | |
4412 | const std::shared_ptr<music::Service> music::Service::Client::instance() |
4413 | { |
4414 | - static std::shared_ptr<music::Service> instance{new music::Service()}; |
4415 | + static std::shared_ptr<music::Service> instance{new music::ServiceStub()}; |
4416 | return instance; |
4417 | } |
4418 | - |
4419 | -music::Service::Service() |
4420 | -{ |
4421 | -} |
4422 | - |
4423 | -music::Service::~Service() |
4424 | -{ |
4425 | -} |
4426 | - |
4427 | -std::shared_ptr<music::Player> music::Service::create_session() |
4428 | -{ |
4429 | - static std::shared_ptr<music::Player> session{new music::Player(shared_from_this())}; |
4430 | - return session; |
4431 | -} |
4432 | |
4433 | === added file 'src/com/ubuntu/music/service_implementation.cpp' |
4434 | --- src/com/ubuntu/music/service_implementation.cpp 1970-01-01 00:00:00 +0000 |
4435 | +++ src/com/ubuntu/music/service_implementation.cpp 2013-11-11 13:09:24 +0000 |
4436 | @@ -0,0 +1,52 @@ |
4437 | +/* |
4438 | + * Copyright © 2013 Canonical Ltd. |
4439 | + * |
4440 | + * This program is free software: you can redistribute it and/or modify it |
4441 | + * under the terms of the GNU Lesser General Public License version 3, |
4442 | + * as published by the Free Software Foundation. |
4443 | + * |
4444 | + * This program is distributed in the hope that it will be useful, |
4445 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4446 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4447 | + * GNU Lesser General Public License for more details. |
4448 | + * |
4449 | + * You should have received a copy of the GNU Lesser General Public License |
4450 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4451 | + * |
4452 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4453 | + */ |
4454 | + |
4455 | +#include "service_implementation.h" |
4456 | + |
4457 | +#include "player_configuration.h" |
4458 | +#include "player_implementation.h" |
4459 | + |
4460 | +#include "gstreamer/engine.h" |
4461 | + |
4462 | +namespace music = com::ubuntu::music; |
4463 | + |
4464 | +struct music::ServiceImplementation::Private |
4465 | +{ |
4466 | + Private() : engine(std::make_shared<gstreamer::Engine>()) |
4467 | + { |
4468 | + } |
4469 | + std::shared_ptr<music::Engine> engine; |
4470 | +}; |
4471 | + |
4472 | +music::ServiceImplementation::ServiceImplementation() : d(new Private()) |
4473 | +{ |
4474 | + |
4475 | +} |
4476 | + |
4477 | +music::ServiceImplementation::~ServiceImplementation() |
4478 | +{ |
4479 | +} |
4480 | + |
4481 | +std::shared_ptr<music::Player> music::ServiceImplementation::create_session( |
4482 | + const music::Player::Configuration& conf) |
4483 | +{ |
4484 | + return std::make_shared<music::PlayerImplementation>( |
4485 | + conf.object_path, |
4486 | + shared_from_this(), |
4487 | + d->engine); |
4488 | +} |
4489 | |
4490 | === added file 'src/com/ubuntu/music/service_implementation.h' |
4491 | --- src/com/ubuntu/music/service_implementation.h 1970-01-01 00:00:00 +0000 |
4492 | +++ src/com/ubuntu/music/service_implementation.h 2013-11-11 13:09:24 +0000 |
4493 | @@ -0,0 +1,46 @@ |
4494 | +/* |
4495 | + * Copyright © 2013 Canonical Ltd. |
4496 | + * |
4497 | + * This program is free software: you can redistribute it and/or modify it |
4498 | + * under the terms of the GNU Lesser General Public License version 3, |
4499 | + * as published by the Free Software Foundation. |
4500 | + * |
4501 | + * This program is distributed in the hope that it will be useful, |
4502 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4503 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4504 | + * GNU Lesser General Public License for more details. |
4505 | + * |
4506 | + * You should have received a copy of the GNU Lesser General Public License |
4507 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4508 | + * |
4509 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4510 | + */ |
4511 | + |
4512 | +#ifndef COM_UBUNTU_MUSIC_SERVICE_IMPLEMENTATION_H_ |
4513 | +#define COM_UBUNTU_MUSIC_SERVICE_IMPLEMENTATION_H_ |
4514 | + |
4515 | +#include "service_skeleton.h" |
4516 | + |
4517 | +namespace com |
4518 | +{ |
4519 | +namespace ubuntu |
4520 | +{ |
4521 | +namespace music |
4522 | +{ |
4523 | +class ServiceImplementation : public ServiceSkeleton |
4524 | +{ |
4525 | + public: |
4526 | + ServiceImplementation (); |
4527 | + ~ServiceImplementation (); |
4528 | + |
4529 | + std::shared_ptr<Player> create_session(const Player::Configuration&); |
4530 | + |
4531 | + private: |
4532 | + struct Private; |
4533 | + std::shared_ptr<Private> d; |
4534 | +}; |
4535 | +} |
4536 | +} |
4537 | +} |
4538 | + |
4539 | +#endif // COM_UBUNTU_MUSIC_SERVICE_IMPLEMENTATION_H_ |
4540 | |
4541 | === added file 'src/com/ubuntu/music/service_skeleton.cpp' |
4542 | --- src/com/ubuntu/music/service_skeleton.cpp 1970-01-01 00:00:00 +0000 |
4543 | +++ src/com/ubuntu/music/service_skeleton.cpp 2013-11-11 13:09:24 +0000 |
4544 | @@ -0,0 +1,111 @@ |
4545 | +/* |
4546 | + * Copyright © 2013 Canonical Ltd. |
4547 | + * |
4548 | + * This program is free software: you can redistribute it and/or modify it |
4549 | + * under the terms of the GNU Lesser General Public License version 3, |
4550 | + * as published by the Free Software Foundation. |
4551 | + * |
4552 | + * This program is distributed in the hope that it will be useful, |
4553 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4554 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4555 | + * GNU Lesser General Public License for more details. |
4556 | + * |
4557 | + * You should have received a copy of the GNU Lesser General Public License |
4558 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4559 | + * |
4560 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4561 | + */ |
4562 | + |
4563 | +#include "service_skeleton.h" |
4564 | + |
4565 | +#include "mpris/service.h" |
4566 | +#include "player_configuration.h" |
4567 | +#include "the_session_bus.h" |
4568 | + |
4569 | +#include <org/freedesktop/dbus/message.h> |
4570 | +#include <org/freedesktop/dbus/types/object_path.h> |
4571 | + |
4572 | +#include <map> |
4573 | +#include <sstream> |
4574 | + |
4575 | +namespace dbus = org::freedesktop::dbus; |
4576 | +namespace music = com::ubuntu::music; |
4577 | + |
4578 | +namespace |
4579 | +{ |
4580 | +std::map<dbus::types::ObjectPath, std::shared_ptr<music::Player>> session_store; |
4581 | +} |
4582 | + |
4583 | +struct music::ServiceSkeleton::Private |
4584 | +{ |
4585 | + Private(music::ServiceSkeleton* impl) |
4586 | + : impl(impl), |
4587 | + object(impl->access_service()->add_object_for_path( |
4588 | + dbus::traits::Service<music::Service>::object_path())) |
4589 | + { |
4590 | + object->install_method_handler<mpris::Service::CreateSession>( |
4591 | + std::bind( |
4592 | + &Private::handle_create_session, |
4593 | + this, |
4594 | + std::placeholders::_1)); |
4595 | + } |
4596 | + |
4597 | + void handle_create_session(DBusMessage* msg) |
4598 | + { |
4599 | + static unsigned int session_counter = 0; |
4600 | + |
4601 | + std::stringstream ss; |
4602 | + ss << "/com/ubuntu/music/Service/sessions/" << session_counter++; |
4603 | + |
4604 | + dbus::types::ObjectPath op{ss.str()}; |
4605 | + music::Player::Configuration config{op}; |
4606 | + |
4607 | + try |
4608 | + { |
4609 | + auto session = impl->create_session(config); |
4610 | + |
4611 | + bool inserted = false; |
4612 | + std::tie(std::ignore, inserted) |
4613 | + = session_store.insert(std::make_pair(op, session)); |
4614 | + |
4615 | + if (!inserted) |
4616 | + throw std::runtime_error("Problem persisting session in session store."); |
4617 | + |
4618 | + auto reply = dbus::Message::make_method_return(msg); |
4619 | + reply->writer() << op; |
4620 | + |
4621 | + impl->access_bus()->send(reply->get()); |
4622 | + } catch(const std::runtime_error& e) |
4623 | + { |
4624 | + auto reply = dbus::Message::make_error( |
4625 | + msg, |
4626 | + mpris::Service::Errors::CreatingSession::name(), |
4627 | + e.what()); |
4628 | + impl->access_bus()->send(reply->get()); |
4629 | + } |
4630 | + } |
4631 | + |
4632 | + music::ServiceSkeleton* impl; |
4633 | + dbus::Object::Ptr object; |
4634 | + |
4635 | +}; |
4636 | + |
4637 | +music::ServiceSkeleton::ServiceSkeleton() |
4638 | + : dbus::Skeleton<music::Service>(the_session_bus()), |
4639 | + d(new Private(this)) |
4640 | +{ |
4641 | +} |
4642 | + |
4643 | +music::ServiceSkeleton::~ServiceSkeleton() |
4644 | +{ |
4645 | +} |
4646 | + |
4647 | +void music::ServiceSkeleton::run() |
4648 | +{ |
4649 | + access_bus()->run(); |
4650 | +} |
4651 | + |
4652 | +void music::ServiceSkeleton::stop() |
4653 | +{ |
4654 | + access_bus()->stop(); |
4655 | +} |
4656 | |
4657 | === added file 'src/com/ubuntu/music/service_skeleton.h' |
4658 | --- src/com/ubuntu/music/service_skeleton.h 1970-01-01 00:00:00 +0000 |
4659 | +++ src/com/ubuntu/music/service_skeleton.h 2013-11-11 13:09:24 +0000 |
4660 | @@ -0,0 +1,53 @@ |
4661 | +/* |
4662 | + * Copyright © 2013 Canonical Ltd. |
4663 | + * |
4664 | + * This program is free software: you can redistribute it and/or modify it |
4665 | + * under the terms of the GNU Lesser General Public License version 3, |
4666 | + * as published by the Free Software Foundation. |
4667 | + * |
4668 | + * This program is distributed in the hope that it will be useful, |
4669 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4670 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4671 | + * GNU Lesser General Public License for more details. |
4672 | + * |
4673 | + * You should have received a copy of the GNU Lesser General Public License |
4674 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4675 | + * |
4676 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4677 | + */ |
4678 | + |
4679 | +#ifndef COM_UBUNTU_MUSIC_SERVICE_SKELETON_H_ |
4680 | +#define COM_UBUNTU_MUSIC_SERVICE_SKELETON_H_ |
4681 | + |
4682 | +#include <com/ubuntu/music/service.h> |
4683 | + |
4684 | +#include "service_traits.h" |
4685 | + |
4686 | +#include <org/freedesktop/dbus/skeleton.h> |
4687 | + |
4688 | +#include <memory> |
4689 | + |
4690 | +namespace com |
4691 | +{ |
4692 | +namespace ubuntu |
4693 | +{ |
4694 | +namespace music |
4695 | +{ |
4696 | +class ServiceSkeleton : public org::freedesktop::dbus::Skeleton<com::ubuntu::music::Service> |
4697 | +{ |
4698 | + public: |
4699 | + ServiceSkeleton(); |
4700 | + ~ServiceSkeleton(); |
4701 | + |
4702 | + void run(); |
4703 | + void stop(); |
4704 | + |
4705 | + private: |
4706 | + struct Private; |
4707 | + std::shared_ptr<Private> d; |
4708 | +}; |
4709 | +} |
4710 | +} |
4711 | +} |
4712 | + |
4713 | +#endif // COM_UBUNTU_MUSIC_SERVICE_SKELETON_H_ |
4714 | |
4715 | === added file 'src/com/ubuntu/music/service_stub.cpp' |
4716 | --- src/com/ubuntu/music/service_stub.cpp 1970-01-01 00:00:00 +0000 |
4717 | +++ src/com/ubuntu/music/service_stub.cpp 2013-11-11 13:09:24 +0000 |
4718 | @@ -0,0 +1,59 @@ |
4719 | +/* |
4720 | + * Copyright © 2013 Canonical Ltd. |
4721 | + * |
4722 | + * This program is free software: you can redistribute it and/or modify it |
4723 | + * under the terms of the GNU Lesser General Public License version 3, |
4724 | + * as published by the Free Software Foundation. |
4725 | + * |
4726 | + * This program is distributed in the hope that it will be useful, |
4727 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4728 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4729 | + * GNU Lesser General Public License for more details. |
4730 | + * |
4731 | + * You should have received a copy of the GNU Lesser General Public License |
4732 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4733 | + * |
4734 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4735 | + */ |
4736 | + |
4737 | +#include "service_stub.h" |
4738 | +#include "service_traits.h" |
4739 | + |
4740 | +#include "player_stub.h" |
4741 | +#include "the_session_bus.h" |
4742 | + |
4743 | +#include "mpris/service.h" |
4744 | + |
4745 | +namespace dbus = org::freedesktop::dbus; |
4746 | +namespace music = com::ubuntu::music; |
4747 | + |
4748 | +struct music::ServiceStub::Private |
4749 | +{ |
4750 | + dbus::Object::Ptr object; |
4751 | +}; |
4752 | + |
4753 | +music::ServiceStub::ServiceStub() |
4754 | + : org::freedesktop::dbus::Stub<music::Service>(the_session_bus()), |
4755 | + d(new Private{ |
4756 | + access_service()->object_for_path( |
4757 | + dbus::types::ObjectPath( |
4758 | + dbus::traits::Service<music::Service>::object_path()))}) |
4759 | +{ |
4760 | +} |
4761 | + |
4762 | +music::ServiceStub::~ServiceStub() |
4763 | +{ |
4764 | +} |
4765 | + |
4766 | +std::shared_ptr<music::Player> music::ServiceStub::create_session(const music::Player::Configuration&) |
4767 | +{ |
4768 | + auto op |
4769 | + = d->object->invoke_method_synchronously< |
4770 | + mpris::Service::CreateSession, |
4771 | + dbus::types::ObjectPath>(); |
4772 | + |
4773 | + if (op.is_error()) |
4774 | + throw std::runtime_error("Problem creating session: " + op.error()); |
4775 | + |
4776 | + return std::shared_ptr<music::Player>(new music::PlayerStub(shared_from_this(), op.value())); |
4777 | +} |
4778 | |
4779 | === added file 'src/com/ubuntu/music/service_stub.h' |
4780 | --- src/com/ubuntu/music/service_stub.h 1970-01-01 00:00:00 +0000 |
4781 | +++ src/com/ubuntu/music/service_stub.h 2013-11-11 13:09:24 +0000 |
4782 | @@ -0,0 +1,52 @@ |
4783 | +/* |
4784 | + * Copyright © 2013 Canonical Ltd. |
4785 | + * |
4786 | + * This program is free software: you can redistribute it and/or modify it |
4787 | + * under the terms of the GNU Lesser General Public License version 3, |
4788 | + * as published by the Free Software Foundation. |
4789 | + * |
4790 | + * This program is distributed in the hope that it will be useful, |
4791 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4792 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4793 | + * GNU Lesser General Public License for more details. |
4794 | + * |
4795 | + * You should have received a copy of the GNU Lesser General Public License |
4796 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4797 | + * |
4798 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4799 | + */ |
4800 | + |
4801 | +#ifndef COM_UBUNTU_MUSIC_SERVICE_STUB_H_ |
4802 | +#define COM_UBUNTU_MUSIC_SERVICE_STUB_H_ |
4803 | + |
4804 | +#include <com/ubuntu/music/service.h> |
4805 | + |
4806 | +#include "service_traits.h" |
4807 | + |
4808 | +#include <org/freedesktop/dbus/stub.h> |
4809 | + |
4810 | +#include <memory> |
4811 | + |
4812 | +namespace com |
4813 | +{ |
4814 | +namespace ubuntu |
4815 | +{ |
4816 | +namespace music |
4817 | +{ |
4818 | +class ServiceStub : public org::freedesktop::dbus::Stub<com::ubuntu::music::Service> |
4819 | +{ |
4820 | + public: |
4821 | + ServiceStub(); |
4822 | + ~ServiceStub(); |
4823 | + |
4824 | + std::shared_ptr<Player> create_session(const Player::Configuration&); |
4825 | + |
4826 | + private: |
4827 | + struct Private; |
4828 | + std::unique_ptr<Private> d; |
4829 | +}; |
4830 | +} |
4831 | +} |
4832 | +} |
4833 | + |
4834 | +#endif // COM_UBUNTU_MUSIC_SERVICE_STUB_H_ |
4835 | |
4836 | === added file 'src/com/ubuntu/music/service_traits.h' |
4837 | --- src/com/ubuntu/music/service_traits.h 1970-01-01 00:00:00 +0000 |
4838 | +++ src/com/ubuntu/music/service_traits.h 2013-11-11 13:09:24 +0000 |
4839 | @@ -0,0 +1,60 @@ |
4840 | +/* |
4841 | + * Copyright © 2013 Canonical Ltd. |
4842 | + * |
4843 | + * This program is free software: you can redistribute it and/or modify it |
4844 | + * under the terms of the GNU Lesser General Public License version 3, |
4845 | + * as published by the Free Software Foundation. |
4846 | + * |
4847 | + * This program is distributed in the hope that it will be useful, |
4848 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4849 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4850 | + * GNU Lesser General Public License for more details. |
4851 | + * |
4852 | + * You should have received a copy of the GNU Lesser General Public License |
4853 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4854 | + * |
4855 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4856 | + */ |
4857 | + |
4858 | +#ifndef COM_UBUNTU_MUSIC_SERVICE_TRAITS_H_ |
4859 | +#define COM_UBUNTU_MUSIC_SERVICE_TRAITS_H_ |
4860 | + |
4861 | +#include <com/ubuntu/music/service.h> |
4862 | + |
4863 | +#include <org/freedesktop/dbus/traits/service.h> |
4864 | + |
4865 | +namespace org |
4866 | +{ |
4867 | +namespace freedesktop |
4868 | +{ |
4869 | +namespace dbus |
4870 | +{ |
4871 | +namespace traits |
4872 | +{ |
4873 | +template<> |
4874 | +struct Service<com::ubuntu::music::Service> |
4875 | +{ |
4876 | + inline static const std::string& interface_name() |
4877 | + { |
4878 | + static const std::string s |
4879 | + { |
4880 | + "com.ubuntu.music.Service" |
4881 | + }; |
4882 | + return s; |
4883 | + } |
4884 | + |
4885 | + inline static const std::string& object_path() |
4886 | + { |
4887 | + static const std::string s |
4888 | + { |
4889 | + "/com/ubuntu/music/Service" |
4890 | + }; |
4891 | + return s; |
4892 | + } |
4893 | +}; |
4894 | +} |
4895 | +} |
4896 | +} |
4897 | +} |
4898 | + |
4899 | +#endif // COM_UBUNTU_MUSIC_SERVICE_TRAITS_H_ |
4900 | |
4901 | === added file 'src/com/ubuntu/music/the_session_bus.cpp' |
4902 | --- src/com/ubuntu/music/the_session_bus.cpp 1970-01-01 00:00:00 +0000 |
4903 | +++ src/com/ubuntu/music/the_session_bus.cpp 2013-11-11 13:09:24 +0000 |
4904 | @@ -0,0 +1,39 @@ |
4905 | +/* |
4906 | + * Copyright © 2013 Canonical Ltd. |
4907 | + * |
4908 | + * This program is free software: you can redistribute it and/or modify it |
4909 | + * under the terms of the GNU Lesser General Public License version 3, |
4910 | + * as published by the Free Software Foundation. |
4911 | + * |
4912 | + * This program is distributed in the hope that it will be useful, |
4913 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4914 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4915 | + * GNU Lesser General Public License for more details. |
4916 | + * |
4917 | + * You should have received a copy of the GNU Lesser General Public License |
4918 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4919 | + * |
4920 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4921 | + */ |
4922 | + |
4923 | +#include "the_session_bus.h" |
4924 | + |
4925 | +#include <org/freedesktop/dbus/asio/executor.h> |
4926 | + |
4927 | +namespace |
4928 | +{ |
4929 | +std::once_flag once; |
4930 | +} |
4931 | + |
4932 | +org::freedesktop::dbus::Bus::Ptr the_session_bus() |
4933 | +{ |
4934 | + static org::freedesktop::dbus::Bus::Ptr bus |
4935 | + = std::make_shared<org::freedesktop::dbus::Bus>( |
4936 | + org::freedesktop::dbus::WellKnownBus::session); |
4937 | + static org::freedesktop::dbus::Executor::Ptr executor |
4938 | + = std::make_shared<org::freedesktop::dbus::asio::Executor>(bus); |
4939 | + |
4940 | + std::call_once(once, [](){bus->install_executor(executor);}); |
4941 | + |
4942 | + return bus; |
4943 | +} |
4944 | |
4945 | === added file 'src/com/ubuntu/music/the_session_bus.h' |
4946 | --- src/com/ubuntu/music/the_session_bus.h 1970-01-01 00:00:00 +0000 |
4947 | +++ src/com/ubuntu/music/the_session_bus.h 2013-11-11 13:09:24 +0000 |
4948 | @@ -0,0 +1,26 @@ |
4949 | +/* |
4950 | + * Copyright © 2013 Canonical Ltd. |
4951 | + * |
4952 | + * This program is free software: you can redistribute it and/or modify it |
4953 | + * under the terms of the GNU Lesser General Public License version 3, |
4954 | + * as published by the Free Software Foundation. |
4955 | + * |
4956 | + * This program is distributed in the hope that it will be useful, |
4957 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4958 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4959 | + * GNU Lesser General Public License for more details. |
4960 | + * |
4961 | + * You should have received a copy of the GNU Lesser General Public License |
4962 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4963 | + * |
4964 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4965 | + */ |
4966 | + |
4967 | +#ifndef THE_SESSION_BUS_H_ |
4968 | +#define THE_SESSION_BUS_H_ |
4969 | + |
4970 | +#include <org/freedesktop/dbus/bus.h> |
4971 | + |
4972 | +org::freedesktop::dbus::Bus::Ptr the_session_bus(); |
4973 | + |
4974 | +#endif // THE_SESSION_BUS_H_ |
4975 | |
4976 | === modified file 'src/com/ubuntu/music/track.cpp' |
4977 | --- src/com/ubuntu/music/track.cpp 2013-08-13 14:07:37 +0000 |
4978 | +++ src/com/ubuntu/music/track.cpp 2013-11-11 13:09:24 +0000 |
4979 | @@ -16,91 +16,19 @@ |
4980 | * Authored by: Thomas Voß <thomas.voss@canonical.com> |
4981 | */ |
4982 | |
4983 | -#include "com/ubuntu/music/track.h" |
4984 | +#include <com/ubuntu/music/track.h> |
4985 | +#include <com/ubuntu/music/property.h> |
4986 | |
4987 | #include <map> |
4988 | |
4989 | namespace music = com::ubuntu::music; |
4990 | |
4991 | -const music::Track::MetaData::KeyType& music::Track::MetaData::track_id_key() |
4992 | -{ |
4993 | - static const KeyType key = "test"; |
4994 | - return key; |
4995 | -} |
4996 | - |
4997 | -struct music::Track::MetaData::Private |
4998 | -{ |
4999 | - std::map<music::Track::MetaData::KeyType, music::Track::MetaData::ValueType> lut; |
5000 | - |
PASSED: Continuous integration, rev:3 jenkins. qa.ubuntu. com/job/ music-hub- ci/5/ jenkins. qa.ubuntu. com/job/ music-hub- saucy-amd64- ci/5 jenkins. qa.ubuntu. com/job/ music-hub- saucy-armhf- ci/5 jenkins. qa.ubuntu. com/job/ music-hub- saucy-armhf- ci/5/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ music-hub- saucy-i386- ci/5
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ music-hub- ci/5/rebuild
http://