Merge lp:~thomas-voss/music-hub/add-backend-and-service-implementation into lp:music-hub

Proposed by Thomas Voß
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
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.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
David Henningsson (diwic) wrote :

Not sure what this is supposed to add, but all files in src/com/ubuntu/music/service/* are empty, and there is no CMakeLists for building them either. Are you sure you pushed the right branch?

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
11. By Thomas Voß

Add missing build dep on google-mock.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
12. By Thomas Voß

Add missing build-dependency on libgstreamer1.0-dev.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
13. By Thomas Voß

Add missing build dependencies.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
14. By Thomas Voß

Fix build dependencies on libboost-system-dev.
Disable two failing tests.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
15. By Thomas Voß

Add build-dependency on libboost-program-options-dev.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+ &current,
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-
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches