Merge lp:~jamesh/mediascanner2/dbus-transport into lp:mediascanner2

Proposed by James Henstridge
Status: Merged
Merged at revision: 232
Proposed branch: lp:~jamesh/mediascanner2/dbus-transport
Merge into: lp:mediascanner2
Prerequisite: lp:~jamesh/mediascanner2/mediafile-constructor
Diff against target: 1336 lines (+1054/-10)
26 files modified
CMakeLists.txt (+2/-0)
debian/control (+4/-0)
debian/mediascanner2.0.install (+2/-0)
src/mediascanner/Album.cc (+3/-0)
src/mediascanner/Album.hh (+1/-1)
src/mediascanner/MediaFile.cc (+3/-0)
src/mediascanner/MediaFile.hh (+1/-1)
src/mediascanner/MediaStore.cc (+1/-1)
src/mediascanner/MediaStore.hh (+1/-1)
src/ms-dbus/CMakeLists.txt (+33/-0)
src/ms-dbus/com.canonical.MediaScanner2.service.in (+3/-0)
src/ms-dbus/dbus-codec.cc (+90/-0)
src/ms-dbus/dbus-codec.hh (+87/-0)
src/ms-dbus/dbus-interface.hh (+153/-0)
src/ms-dbus/main.cc (+38/-0)
src/ms-dbus/service-skeleton.cc (+232/-0)
src/ms-dbus/service-skeleton.hh (+51/-0)
src/ms-dbus/service-stub.cc (+103/-0)
src/ms-dbus/service-stub.hh (+61/-0)
src/ms-dbus/service.hh (+62/-0)
src/qml/Ubuntu/MediaScanner/CMakeLists.txt (+2/-1)
src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc (+15/-1)
src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.hh (+3/-2)
test/CMakeLists.txt (+6/-2)
test/test_dbus.cc (+67/-0)
test/test_qml.cc (+30/-0)
To merge this branch: bzr merge lp:~jamesh/mediascanner2/dbus-transport
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Jussi Pakkanen (community) Needs Fixing
Review via email: mp+220752@code.launchpad.net

Commit message

Add a D-Bus service exposing the MediaStore, and move the QML binding over to using it.

Description of the change

Add a D-Bus service exposing the MediaStore, and move the QML binding over to using it.

Eventually the libmediascanner MediaStore API should be going through this API, but I decided to move the QML binding over first before refactoring the core.

The impetus for this change is to allow for more fine grained control of access to the index from confined applications (which is also to come).

The no-argument MediaFile and Album constructors were necessary to work with libdbus-cpp's templates.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
252. By James Henstridge

Build-Depend on libdbus-1-dev.

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

Build-Depend on libproperties-cpp-dev.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

Looking good. All the dbus stuff is nicely isolated in its own thing away from the core. There are a few issues, though, but they are more fundamental than actual code problems.

> +set_target_properties(ms-dbus PROPERTIES COMPILE_FLAGS "-fPIC")

I assume this is because this library is used as part of the qml module? If yes, please add a comment above this line saying so.

> The no-argument MediaFile and Album constructors were necessary to work with
> libdbus-cpp's templates.

This is bad. It destroys the security we worked so hard to build into Mediafiles, namely that it is very hard to construct an invalid one. I would classify this as a bug in dbus-cpp, an RPC library should not place these sorts of requirements on the classes it handles. Could you file a bug on dbus-cpp about this with all the necessary information?

I'm also worried about the mixed technologies here. We are already dealing with quite a lot of Qt stuff and instead of using Qt's dbus system we use a different one. But since that ship has already sailed, let's go with this. We can always change it later thanks to the proper isolation of dbus from the core.

review: Needs Fixing
254. By James Henstridge

Add a comment explaining why the helper D-Bus library is linked with -fPIC.

Revision history for this message
James Henstridge (jamesh) wrote :

I've added a comment to the make file.

I've filed a bug report here:

https://bugs.launchpad.net/dbus-cpp/+bug/1322611

For reference, here is the class that required the default constructors:

http://bazaar.launchpad.net/~phablet-team/dbus-cpp/trunk/view/head:/include/core/dbus/result.h#L36

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
255. By James Henstridge

Remove some excess debug logging.

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

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 2014-03-28 03:43:17 +0000
3+++ CMakeLists.txt 2014-05-24 09:41:18 +0000
4@@ -15,6 +15,7 @@
5 sqlite3
6 )
7 pkg_check_modules(GST gstreamer-1.0 gstreamer-pbutils-1.0 REQUIRED)
8+pkg_check_modules(DBUSCPP dbus-cpp REQUIRED)
9 find_package(Threads REQUIRED)
10 find_package(Qt5Core REQUIRED)
11
12@@ -32,6 +33,7 @@
13
14 add_subdirectory(src/mediascanner)
15 add_subdirectory(src/daemon)
16+add_subdirectory(src/ms-dbus)
17 add_subdirectory(src/qml/Ubuntu/MediaScanner)
18 add_subdirectory(src/utils)
19 add_subdirectory(test)
20
21=== modified file 'debian/control'
22--- debian/control 2014-03-28 03:43:17 +0000
23+++ debian/control 2014-05-24 09:41:18 +0000
24@@ -4,11 +4,15 @@
25 Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com>
26 Standards-Version: 3.9.5
27 Build-Depends: cmake,
28+ dbus,
29 debhelper (>= 9),
30+ libdbus-1-dev,
31+ libdbus-cpp-dev (>= 3.0.0),
32 libglib2.0-dev,
33 libgstreamer-plugins-base1.0-dev,
34 libgstreamer1.0-dev,
35 libgtest-dev,
36+ libproperties-cpp-dev,
37 libsqlite3-dev,
38 qt5-default,
39 qtbase5-dev,
40
41=== modified file 'debian/mediascanner2.0.install'
42--- debian/mediascanner2.0.install 2013-12-18 10:57:10 +0000
43+++ debian/mediascanner2.0.install 2014-05-24 09:41:18 +0000
44@@ -1,2 +1,4 @@
45 usr/bin/*
46+usr/lib/*/mediascanner-2.0/mediascanner-dbus-2.0
47+usr/share/dbus-1/services/*
48 usr/share/upstart/sessions/*
49
50=== modified file 'src/mediascanner/Album.cc'
51--- src/mediascanner/Album.cc 2014-01-31 08:21:13 +0000
52+++ src/mediascanner/Album.cc 2014-05-24 09:41:18 +0000
53@@ -23,6 +23,9 @@
54
55 namespace mediascanner {
56
57+Album::Album() {
58+}
59+
60 Album::Album(const std::string &title, const std::string &artist)
61 : title(title), artist(artist) {
62 }
63
64=== modified file 'src/mediascanner/Album.hh'
65--- src/mediascanner/Album.hh 2014-01-31 08:21:13 +0000
66+++ src/mediascanner/Album.hh 2014-05-24 09:41:18 +0000
67@@ -27,8 +27,8 @@
68 class Album final {
69 public:
70
71+ Album();
72 Album(const std::string &title, const std::string &artist);
73- Album() = delete;
74
75 const std::string& getTitle() const noexcept;
76 const std::string& getArtist() const noexcept;
77
78=== modified file 'src/mediascanner/MediaFile.cc'
79--- src/mediascanner/MediaFile.cc 2014-05-24 09:41:18 +0000
80+++ src/mediascanner/MediaFile.cc 2014-05-24 09:41:18 +0000
81@@ -26,6 +26,9 @@
82
83 namespace mediascanner {
84
85+MediaFile::MediaFile() : p(new MediaFilePrivate) {
86+}
87+
88 MediaFile::MediaFile(const MediaFile &other) :
89 p(new MediaFilePrivate(*other.p)) {
90 }
91
92=== modified file 'src/mediascanner/MediaFile.hh'
93--- src/mediascanner/MediaFile.hh 2014-05-24 09:41:18 +0000
94+++ src/mediascanner/MediaFile.hh 2014-05-24 09:41:18 +0000
95@@ -32,7 +32,7 @@
96 friend class MediaFileBuilder;
97 public:
98
99- MediaFile() = delete;
100+ MediaFile();
101 MediaFile(const MediaFile &other);
102 MediaFile(const MediaFileBuilder &builder);
103 MediaFile(MediaFileBuilder &&builder);
104
105=== modified file 'src/mediascanner/MediaStore.cc'
106--- src/mediascanner/MediaStore.cc 2014-05-24 09:41:18 +0000
107+++ src/mediascanner/MediaStore.cc 2014-05-24 09:41:18 +0000
108@@ -514,7 +514,7 @@
109 return collect_albums(query);
110 }
111
112-vector<std::string> MediaStore::listArtists(bool album_artists, int limit) {
113+vector<std::string> MediaStore::listArtists(bool album_artists, int limit) const {
114 const char *qs;
115
116 if (album_artists) {
117
118=== modified file 'src/mediascanner/MediaStore.hh'
119--- src/mediascanner/MediaStore.hh 2014-02-28 06:47:48 +0000
120+++ src/mediascanner/MediaStore.hh 2014-05-24 09:41:18 +0000
121@@ -55,7 +55,7 @@
122 std::string getETag(const std::string &filename) const;
123 std::vector<MediaFile> listSongs(const std::string& artist="", const std::string& album="", const std::string& album_artist="", int limit=-1) const;
124 std::vector<Album> listAlbums(const std::string& artist="", const std::string& album_artist="", int limit=-1) const;
125- std::vector<std::string> listArtists(bool album_artists, int limit=-1);
126+ std::vector<std::string> listArtists(bool album_artists, int limit=-1) const;
127
128 size_t size() const;
129 void pruneDeleted();
130
131=== added directory 'src/ms-dbus'
132=== added file 'src/ms-dbus/CMakeLists.txt'
133--- src/ms-dbus/CMakeLists.txt 1970-01-01 00:00:00 +0000
134+++ src/ms-dbus/CMakeLists.txt 2014-05-24 09:41:18 +0000
135@@ -0,0 +1,33 @@
136+include_directories(..)
137+add_definitions(${MEDIASCANNER_CFLAGS} ${DBUSCPP_CFLAGS})
138+
139+add_library(ms-dbus STATIC
140+ dbus-codec.cc
141+ service-skeleton.cc
142+ service-stub.cc
143+)
144+
145+target_link_libraries(ms-dbus mediascanner ${DBUSCPP_LDFLAGS})
146+# Compile with -fPIC, since this code is linked into the QML plugin.
147+set_target_properties(ms-dbus PROPERTIES COMPILE_FLAGS "-fPIC")
148+
149+add_executable(mediascanner-dbus
150+ main.cc
151+)
152+target_link_libraries(mediascanner-dbus ms-dbus)
153+set_target_properties(mediascanner-dbus
154+ PROPERTIES OUTPUT_NAME "mediascanner-dbus-2.0")
155+
156+install(
157+ TARGETS mediascanner-dbus
158+ RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/mediascanner-2.0
159+)
160+
161+configure_file(
162+ com.canonical.MediaScanner2.service.in
163+ com.canonical.MediaScanner2.service)
164+
165+install(
166+ FILES ${CMAKE_CURRENT_BINARY_DIR}/com.canonical.MediaScanner2.service
167+ DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services
168+)
169
170=== added file 'src/ms-dbus/com.canonical.MediaScanner2.service.in'
171--- src/ms-dbus/com.canonical.MediaScanner2.service.in 1970-01-01 00:00:00 +0000
172+++ src/ms-dbus/com.canonical.MediaScanner2.service.in 2014-05-24 09:41:18 +0000
173@@ -0,0 +1,3 @@
174+[D-BUS Service]
175+Name=com.canonical.Thumbnailer
176+Exec=@CMAKE_INSTALL_LIBDIR@/mediascanner-2.0/mediascanner-dbus-2.0
177
178=== added file 'src/ms-dbus/dbus-codec.cc'
179--- src/ms-dbus/dbus-codec.cc 1970-01-01 00:00:00 +0000
180+++ src/ms-dbus/dbus-codec.cc 2014-05-24 09:41:18 +0000
181@@ -0,0 +1,90 @@
182+/*
183+ * Copyright (C) 2013 Canonical, Ltd.
184+ *
185+ * Authors:
186+ * James Henstridge <james.henstridge@canonical.com>
187+ *
188+ * This program is free software: you can redistribute it and/or modify
189+ * it under the terms of the GNU Lesser General Public License version 3 as
190+ * published by the Free Software Foundation.
191+ *
192+ * This program is distributed in the hope that it will be useful,
193+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
194+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
195+ * GNU Lesser General Public License for more details.
196+ *
197+ * You should have received a copy of the GNU Lesser General Public License
198+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
199+ */
200+#include <cstdint>
201+#include <string>
202+
203+#include <core/dbus/object.h>
204+
205+#include <mediascanner/MediaFile.hh>
206+#include <mediascanner/MediaFileBuilder.hh>
207+#include <mediascanner/Album.hh>
208+#include "dbus-codec.hh"
209+
210+using core::dbus::Message;
211+using core::dbus::Codec;
212+using mediascanner::MediaFile;
213+using mediascanner::MediaFileBuilder;
214+using mediascanner::MediaType;
215+using mediascanner::Album;
216+using std::string;
217+
218+void Codec<MediaFile>::encode_argument(Message::Writer &out, const MediaFile &file) {
219+ auto w = out.open_structure();
220+ core::dbus::encode_argument(w, file.getFileName());
221+ core::dbus::encode_argument(w, file.getContentType());
222+ core::dbus::encode_argument(w, file.getETag());
223+ core::dbus::encode_argument(w, file.getTitle());
224+ core::dbus::encode_argument(w, file.getAuthor());
225+ core::dbus::encode_argument(w, file.getAlbum());
226+ core::dbus::encode_argument(w, file.getAlbumArtist());
227+ core::dbus::encode_argument(w, file.getDate());
228+ core::dbus::encode_argument(w, file.getGenre());
229+ core::dbus::encode_argument(w, (int32_t)file.getDiscNumber());
230+ core::dbus::encode_argument(w, (int32_t)file.getTrackNumber());
231+ core::dbus::encode_argument(w, (int32_t)file.getDuration());
232+ core::dbus::encode_argument(w, (int32_t)file.getType());
233+ out.close_structure(std::move(w));
234+}
235+
236+void Codec<MediaFile>::decode_argument(Message::Reader &in, MediaFile &file) {
237+ auto r = in.pop_structure();
238+ string filename, content_type, etag, title, author;
239+ string album, album_artist, date, genre;
240+ int32_t disc_number, track_number, duration, type;
241+ r >> filename >> content_type >> etag >> title >> author
242+ >> album >> album_artist >> date >> genre
243+ >> disc_number >> track_number >> duration >> type;
244+ file = MediaFileBuilder(filename)
245+ .setContentType(content_type)
246+ .setETag(etag)
247+ .setTitle(title)
248+ .setAuthor(author)
249+ .setAlbum(album)
250+ .setAlbumArtist(album_artist)
251+ .setDate(date)
252+ .setGenre(genre)
253+ .setDiscNumber(disc_number)
254+ .setTrackNumber(track_number)
255+ .setDuration(duration)
256+ .setType((MediaType)type);
257+}
258+
259+void Codec<Album>::encode_argument(Message::Writer &out, const Album &album) {
260+ auto w = out.open_structure();
261+ core::dbus::encode_argument(w, album.getTitle());
262+ core::dbus::encode_argument(w, album.getArtist());
263+ out.close_structure(std::move(w));
264+}
265+
266+void Codec<Album>::decode_argument(Message::Reader &in, Album &album) {
267+ auto r = in.pop_structure();
268+ string title, artist;
269+ r >> title >> artist;
270+ album = Album(title, artist);
271+}
272
273=== added file 'src/ms-dbus/dbus-codec.hh'
274--- src/ms-dbus/dbus-codec.hh 1970-01-01 00:00:00 +0000
275+++ src/ms-dbus/dbus-codec.hh 2014-05-24 09:41:18 +0000
276@@ -0,0 +1,87 @@
277+/*
278+ * Copyright (C) 2013 Canonical, Ltd.
279+ *
280+ * Authors:
281+ * James Henstridge <james.henstridge@canonical.com>
282+ *
283+ * This program is free software: you can redistribute it and/or modify
284+ * it under the terms of the GNU Lesser General Public License version 3 as
285+ * published by the Free Software Foundation.
286+ *
287+ * This program is distributed in the hope that it will be useful,
288+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
289+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290+ * GNU Lesser General Public License for more details.
291+ *
292+ * You should have received a copy of the GNU Lesser General Public License
293+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
294+ */
295+#ifndef MEDIASCANNER_DBUS_CODEC_HH
296+#define MEDIASCANNER_DBUS_CODEC_HH
297+
298+#include <string>
299+
300+#include <core/dbus/codec.h>
301+#include <core/dbus/helper/type_mapper.h>
302+
303+namespace mediascanner {
304+class MediaFile;
305+class Album;
306+}
307+
308+namespace core {
309+namespace dbus {
310+
311+template <>
312+struct Codec<mediascanner::MediaFile> {
313+ static void encode_argument(Message::Writer &out, const mediascanner::MediaFile &file);
314+ static void decode_argument(Message::Reader &in, mediascanner::MediaFile &file);
315+};
316+
317+template <>
318+struct Codec<mediascanner::Album> {
319+ static void encode_argument(Message::Writer &out, const mediascanner::Album &album);
320+ static void decode_argument(Message::Reader &in, mediascanner::Album &album);
321+};
322+
323+namespace helper {
324+
325+template<>
326+struct TypeMapper<mediascanner::MediaFile> {
327+ constexpr static ArgumentType type_value() {
328+ return ArgumentType::structure;
329+ }
330+ constexpr static bool is_basic_type() {
331+ return false;
332+ }
333+ constexpr static bool requires_signature() {
334+ return true;
335+ }
336+ static const std::string &signature() {
337+ static const std::string s = "(sssssssssiiii)";
338+ return s;
339+ }
340+};
341+
342+template<>
343+struct TypeMapper<mediascanner::Album> {
344+ constexpr static ArgumentType type_value() {
345+ return ArgumentType::structure;
346+ }
347+ constexpr static bool is_basic_type() {
348+ return false;
349+ }
350+ constexpr static bool requires_signature() {
351+ return true;
352+ }
353+ static const std::string &signature() {
354+ static const std::string s = "(ss)";
355+ return s;
356+ }
357+};
358+
359+}
360+
361+}
362+}
363+#endif
364
365=== added file 'src/ms-dbus/dbus-interface.hh'
366--- src/ms-dbus/dbus-interface.hh 1970-01-01 00:00:00 +0000
367+++ src/ms-dbus/dbus-interface.hh 2014-05-24 09:41:18 +0000
368@@ -0,0 +1,153 @@
369+/*
370+ * Copyright (C) 2013 Canonical, Ltd.
371+ *
372+ * Authors:
373+ * James Henstridge <james.henstridge@canonical.com>
374+ *
375+ * This program is free software: you can redistribute it and/or modify
376+ * it under the terms of the GNU Lesser General Public License version 3 as
377+ * published by the Free Software Foundation.
378+ *
379+ * This program is distributed in the hope that it will be useful,
380+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
381+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
382+ * GNU Lesser General Public License for more details.
383+ *
384+ * You should have received a copy of the GNU Lesser General Public License
385+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
386+ */
387+#ifndef MEDIASCANNER_DBUS_INTERFACE_HH
388+#define MEDIASCANNER_DBUS_INTERFACE_HH
389+
390+#include <chrono>
391+#include <string>
392+
393+#include <core/dbus/object.h>
394+#include <core/dbus/service.h>
395+
396+namespace mediascanner {
397+namespace dbus {
398+
399+struct MediaStoreInterface {
400+ inline static const std::string& name() {
401+ static std::string s = "com.canonical.MediaScanner2";
402+ return s;
403+ }
404+
405+ struct Errors {
406+ struct Error {
407+ inline static const std::string& name() {
408+ static std::string s = "com.canonical.MediaScanner2.Error";
409+ return s;
410+ }
411+ };
412+ };
413+
414+ struct Lookup {
415+ typedef MediaStoreInterface Interface;
416+
417+ inline static const std::string& name() {
418+ static std::string s = "Lookup";
419+ return s;
420+ }
421+
422+ inline static const std::chrono::milliseconds default_timeout() {
423+ return std::chrono::seconds{1};
424+ }
425+ };
426+
427+ struct Query {
428+ typedef MediaStoreInterface Interface;
429+
430+ inline static const std::string& name() {
431+ static std::string s = "Query";
432+ return s;
433+ }
434+
435+ inline static const std::chrono::milliseconds default_timeout() {
436+ return std::chrono::seconds{1};
437+ }
438+ };
439+
440+ struct QueryAlbums {
441+ typedef MediaStoreInterface Interface;
442+
443+ inline static const std::string& name() {
444+ static std::string s = "QueryAlbums";
445+ return s;
446+ }
447+
448+ inline static const std::chrono::milliseconds default_timeout() {
449+ return std::chrono::seconds{1};
450+ }
451+ };
452+
453+ struct GetAlbumSongs {
454+ typedef MediaStoreInterface Interface;
455+
456+ inline static const std::string& name() {
457+ static std::string s = "GetAlbumSongs";
458+ return s;
459+ }
460+
461+ inline static const std::chrono::milliseconds default_timeout() {
462+ return std::chrono::seconds{1};
463+ }
464+ };
465+
466+ struct GetETag {
467+ typedef MediaStoreInterface Interface;
468+
469+ inline static const std::string& name() {
470+ static std::string s = "GetETag";
471+ return s;
472+ }
473+
474+ inline static const std::chrono::milliseconds default_timeout() {
475+ return std::chrono::seconds{1};
476+ }
477+ };
478+
479+ struct ListSongs {
480+ typedef MediaStoreInterface Interface;
481+
482+ inline static const std::string& name() {
483+ static std::string s = "ListSongs";
484+ return s;
485+ }
486+
487+ inline static const std::chrono::milliseconds default_timeout() {
488+ return std::chrono::seconds{1};
489+ }
490+ };
491+
492+ struct ListAlbums {
493+ typedef MediaStoreInterface Interface;
494+
495+ inline static const std::string& name() {
496+ static std::string s = "ListAlbums";
497+ return s;
498+ }
499+
500+ inline static const std::chrono::milliseconds default_timeout() {
501+ return std::chrono::seconds{1};
502+ }
503+ };
504+
505+ struct ListArtists {
506+ typedef MediaStoreInterface Interface;
507+
508+ inline static const std::string& name() {
509+ static std::string s = "ListArtists";
510+ return s;
511+ }
512+
513+ inline static const std::chrono::milliseconds default_timeout() {
514+ return std::chrono::seconds{1};
515+ }
516+ };
517+};
518+
519+}
520+}
521+#endif
522
523=== added file 'src/ms-dbus/main.cc'
524--- src/ms-dbus/main.cc 1970-01-01 00:00:00 +0000
525+++ src/ms-dbus/main.cc 2014-05-24 09:41:18 +0000
526@@ -0,0 +1,38 @@
527+/*
528+ * Copyright (C) 2013 Canonical, Ltd.
529+ *
530+ * Authors:
531+ * James Henstridge <james.henstridge@canonical.com>
532+ *
533+ * This program is free software: you can redistribute it and/or modify
534+ * it under the terms of the GNU Lesser General Public License version 3 as
535+ * published by the Free Software Foundation.
536+ *
537+ * This program is distributed in the hope that it will be useful,
538+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
539+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
540+ * GNU Lesser General Public License for more details.
541+ *
542+ * You should have received a copy of the GNU Lesser General Public License
543+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
544+ */
545+
546+#include <memory>
547+#include <core/dbus/bus.h>
548+#include <core/dbus/asio/executor.h>
549+
550+#include <mediascanner/MediaStore.hh>
551+#include "service-skeleton.hh"
552+
553+using namespace mediascanner;
554+
555+int main(int , char **) {
556+ auto bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
557+ bus->install_executor(core::dbus::asio::make_executor(bus));
558+
559+ auto store = std::make_shared<MediaStore>(MS_READ_ONLY);
560+
561+ dbus::ServiceSkeleton service(bus, store);
562+ service.run();
563+ return 0;
564+}
565
566=== added file 'src/ms-dbus/service-skeleton.cc'
567--- src/ms-dbus/service-skeleton.cc 1970-01-01 00:00:00 +0000
568+++ src/ms-dbus/service-skeleton.cc 2014-05-24 09:41:18 +0000
569@@ -0,0 +1,232 @@
570+#include <stdexcept>
571+
572+#include <core/dbus/message.h>
573+#include <core/dbus/object.h>
574+#include <core/dbus/types/object_path.h>
575+
576+#include <mediascanner/Album.hh>
577+#include <mediascanner/MediaFile.hh>
578+#include <mediascanner/MediaStore.hh>
579+
580+#include "dbus-interface.hh"
581+#include "dbus-codec.hh"
582+#include "service-skeleton.hh"
583+
584+using core::dbus::Message;
585+
586+namespace mediascanner {
587+namespace dbus {
588+
589+struct ServiceSkeleton::Private {
590+ ServiceSkeleton *impl;
591+ std::shared_ptr<MediaStore> store;
592+ core::dbus::Object::Ptr object;
593+
594+ Private(ServiceSkeleton *impl, std::shared_ptr<MediaStore> store) :
595+ impl(impl),
596+ store(store),
597+ object(impl->access_service()->add_object_for_path(
598+ core::dbus::traits::Service<MediaStoreService>::object_path())) {
599+ object->install_method_handler<MediaStoreInterface::Lookup>(
600+ std::bind(
601+ &Private::handle_lookup,
602+ this,
603+ std::placeholders::_1));
604+ object->install_method_handler<MediaStoreInterface::Query>(
605+ std::bind(
606+ &Private::handle_query,
607+ this,
608+ std::placeholders::_1));
609+ object->install_method_handler<MediaStoreInterface::QueryAlbums>(
610+ std::bind(
611+ &Private::handle_query_albums,
612+ this,
613+ std::placeholders::_1));
614+ object->install_method_handler<MediaStoreInterface::GetAlbumSongs>(
615+ std::bind(
616+ &Private::handle_get_album_songs,
617+ this,
618+ std::placeholders::_1));
619+ object->install_method_handler<MediaStoreInterface::GetETag>(
620+ std::bind(
621+ &Private::handle_get_etag,
622+ this,
623+ std::placeholders::_1));
624+ object->install_method_handler<MediaStoreInterface::ListSongs>(
625+ std::bind(
626+ &Private::handle_list_songs,
627+ this,
628+ std::placeholders::_1));
629+ object->install_method_handler<MediaStoreInterface::ListAlbums>(
630+ std::bind(
631+ &Private::handle_list_albums,
632+ this,
633+ std::placeholders::_1));
634+ object->install_method_handler<MediaStoreInterface::ListArtists>(
635+ std::bind(
636+ &Private::handle_list_artists,
637+ this,
638+ std::placeholders::_1));
639+ }
640+
641+ void handle_lookup(const Message::Ptr &message) {
642+ std::string filename;
643+ message->reader() >> filename;
644+ Message::Ptr reply;
645+ try {
646+ MediaFile file = store->lookup(filename);
647+ reply = Message::make_method_return(message);
648+ reply->writer() << file;
649+ } catch (const std::exception &e) {
650+ reply = Message::make_error(
651+ message, MediaStoreInterface::Errors::Error::name(),
652+ e.what());
653+ }
654+ impl->access_bus()->send(reply);
655+ }
656+
657+ void handle_query(const Message::Ptr &message) {
658+ std::string query;
659+ int32_t type;
660+ int32_t limit;
661+
662+ message->reader() >> query >> type >> limit;
663+ Message::Ptr reply;
664+ try {
665+ auto results = store->query(query, (MediaType)type, limit);
666+ reply = Message::make_method_return(message);
667+ reply->writer() << results;
668+ } catch (const std::exception &e) {
669+ reply = Message::make_error(
670+ message, MediaStoreInterface::Errors::Error::name(),
671+ e.what());
672+ }
673+ impl->access_bus()->send(reply);
674+ }
675+
676+ void handle_query_albums(const Message::Ptr &message) {
677+ std::string query;
678+ int32_t limit;
679+
680+ message->reader() >> query >> limit;
681+ Message::Ptr reply;
682+ try {
683+ auto albums = store->queryAlbums(query, limit);
684+ reply = Message::make_method_return(message);
685+ reply->writer() << albums;
686+ } catch (const std::exception &e) {
687+ reply = Message::make_error(
688+ message, MediaStoreInterface::Errors::Error::name(),
689+ e.what());
690+ }
691+ impl->access_bus()->send(reply);
692+ }
693+
694+ void handle_get_album_songs(const Message::Ptr &message) {
695+ Album album("", "");
696+
697+ message->reader() >> album;
698+ Message::Ptr reply;
699+ try {
700+ auto results = store->getAlbumSongs(album);
701+ reply = Message::make_method_return(message);
702+ reply->writer() << results;
703+ } catch (const std::exception &e) {
704+ reply = Message::make_error(
705+ message, MediaStoreInterface::Errors::Error::name(),
706+ e.what());
707+ }
708+ impl->access_bus()->send(reply);
709+ }
710+
711+ void handle_get_etag(const Message::Ptr &message) {
712+ std::string filename;
713+ message->reader() >> filename;
714+
715+ Message::Ptr reply;
716+ try {
717+ std::string etag = store->getETag(filename);
718+ reply = Message::make_method_return(message);
719+ reply->writer() << etag;
720+ } catch (const std::exception &e) {
721+ reply = Message::make_error(
722+ message, MediaStoreInterface::Errors::Error::name(),
723+ e.what());
724+ }
725+ impl->access_bus()->send(reply);
726+ }
727+
728+ void handle_list_songs(const Message::Ptr &message) {
729+ std::string artist, album, album_artist;
730+ int32_t limit;
731+
732+ message->reader() >> artist >> album >> album_artist >> limit;
733+ Message::Ptr reply;
734+ try {
735+ auto results = store->listSongs(artist, album, album_artist, limit);
736+ reply = Message::make_method_return(message);
737+ reply->writer() << results;
738+ } catch (const std::exception &e) {
739+ reply = Message::make_error(
740+ message, MediaStoreInterface::Errors::Error::name(),
741+ e.what());
742+ }
743+ impl->access_bus()->send(reply);
744+ }
745+
746+ void handle_list_albums(const Message::Ptr &message) {
747+ std::string artist, album_artist;
748+ int32_t limit;
749+
750+ message->reader() >> artist >> album_artist >> limit;
751+ Message::Ptr reply;
752+ try {
753+ auto albums = store->listAlbums(artist, album_artist, limit);
754+ reply = Message::make_method_return(message);
755+ reply->writer() << albums;
756+ } catch (const std::exception &e) {
757+ reply = Message::make_error(
758+ message, MediaStoreInterface::Errors::Error::name(),
759+ e.what());
760+ }
761+ impl->access_bus()->send(reply);
762+ }
763+
764+ void handle_list_artists(const Message::Ptr &message) {
765+ bool album_artists;
766+ int32_t limit;
767+
768+ message->reader() >> album_artists >> limit;
769+ Message::Ptr reply;
770+ try {
771+ auto artists = store->listArtists(album_artists, limit);
772+ reply = Message::make_method_return(message);
773+ reply->writer() << artists;
774+ } catch (const std::exception &e) {
775+ reply = Message::make_error(
776+ message, MediaStoreInterface::Errors::Error::name(),
777+ e.what());
778+ }
779+ impl->access_bus()->send(reply);
780+ }
781+};
782+
783+ServiceSkeleton::ServiceSkeleton(core::dbus::Bus::Ptr bus,
784+ std::shared_ptr<MediaStore> store) :
785+ core::dbus::Skeleton<MediaStoreService>(bus),
786+ p(new Private(this, store)) {
787+}
788+
789+ServiceSkeleton::~ServiceSkeleton() {
790+}
791+
792+void ServiceSkeleton::run() {
793+ access_bus()->run();
794+}
795+
796+void ServiceSkeleton::stop() {
797+ access_bus()->stop();
798+}
799+
800+}
801+}
802
803=== added file 'src/ms-dbus/service-skeleton.hh'
804--- src/ms-dbus/service-skeleton.hh 1970-01-01 00:00:00 +0000
805+++ src/ms-dbus/service-skeleton.hh 2014-05-24 09:41:18 +0000
806@@ -0,0 +1,51 @@
807+/*
808+ * Copyright (C) 2013 Canonical, Ltd.
809+ *
810+ * Authors:
811+ * James Henstridge <james.henstridge@canonical.com>
812+ *
813+ * This program is free software: you can redistribute it and/or modify
814+ * it under the terms of the GNU Lesser General Public License version 3 as
815+ * published by the Free Software Foundation.
816+ *
817+ * This program is distributed in the hope that it will be useful,
818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
819+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
820+ * GNU Lesser General Public License for more details.
821+ *
822+ * You should have received a copy of the GNU Lesser General Public License
823+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
824+ */
825+
826+#ifndef MEDIASCANNER_DBUS_SERVICE_SKELETON_HH
827+#define MEDIASCANNER_DBUS_SERVICE_SKELETON_HH
828+
829+#include <memory>
830+#include <core/dbus/bus.h>
831+#include <core/dbus/skeleton.h>
832+
833+#include "service.hh"
834+
835+namespace mediascanner {
836+
837+class MediaStore;
838+
839+namespace dbus {
840+
841+class ServiceSkeleton : public core::dbus::Skeleton<MediaStoreService> {
842+public:
843+ ServiceSkeleton(core::dbus::Bus::Ptr bus, std::shared_ptr<MediaStore> store);
844+ ~ServiceSkeleton();
845+
846+ void run();
847+ void stop();
848+
849+private:
850+ struct Private;
851+ std::unique_ptr<Private> p;
852+};
853+
854+}
855+}
856+
857+#endif
858
859=== added file 'src/ms-dbus/service-stub.cc'
860--- src/ms-dbus/service-stub.cc 1970-01-01 00:00:00 +0000
861+++ src/ms-dbus/service-stub.cc 2014-05-24 09:41:18 +0000
862@@ -0,0 +1,103 @@
863+/*
864+ * Copyright (C) 2013 Canonical, Ltd.
865+ *
866+ * Authors:
867+ * James Henstridge <james.henstridge@canonical.com>
868+ *
869+ * This program is free software: you can redistribute it and/or modify
870+ * it under the terms of the GNU Lesser General Public License version 3 as
871+ * published by the Free Software Foundation.
872+ *
873+ * This program is distributed in the hope that it will be useful,
874+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
875+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
876+ * GNU Lesser General Public License for more details.
877+ *
878+ * You should have received a copy of the GNU Lesser General Public License
879+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
880+ */
881+
882+#include <stdexcept>
883+
884+#include <mediascanner/Album.hh>
885+#include <mediascanner/MediaFile.hh>
886+#include "service-stub.hh"
887+#include "dbus-interface.hh"
888+#include "dbus-codec.hh"
889+
890+using std::string;
891+
892+namespace mediascanner {
893+namespace dbus {
894+
895+struct ServiceStub::Private
896+{
897+ core::dbus::Object::Ptr object;
898+};
899+
900+ServiceStub::ServiceStub(core::dbus::Bus::Ptr bus)
901+ : core::dbus::Stub<MediaStoreService>(bus),
902+ p(new Private{access_service()->object_for_path(
903+ core::dbus::types::ObjectPath(core::dbus::traits::Service<MediaStoreService>::object_path()))}) {
904+}
905+
906+ServiceStub::~ServiceStub() {
907+}
908+
909+MediaFile ServiceStub::lookup(const string &filename) const {
910+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::Lookup, MediaFile>(filename);
911+ if (result.is_error())
912+ throw std::runtime_error(result.error().print());
913+ return result.value();
914+}
915+
916+std::vector<MediaFile> ServiceStub::query(const string &q, MediaType type, int limit) const {
917+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::Query, std::vector<MediaFile>>(q, (int32_t)type, (int32_t)limit);
918+ if (result.is_error())
919+ throw std::runtime_error(result.error().print());
920+ return result.value();
921+}
922+
923+std::vector<Album> ServiceStub::queryAlbums(const string &core_term, int limit) const {
924+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::QueryAlbums, std::vector<Album>>(core_term, (int32_t)limit);
925+ if (result.is_error())
926+ throw std::runtime_error(result.error().print());
927+ return result.value();
928+}
929+
930+std::vector<MediaFile> ServiceStub::getAlbumSongs(const Album& album) const {
931+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::GetAlbumSongs, std::vector<MediaFile>>(album);
932+ if (result.is_error())
933+ throw std::runtime_error(result.error().print());
934+ return result.value();
935+}
936+
937+string ServiceStub::getETag(const string &filename) const {
938+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::GetETag, string>(filename);
939+ if (result.is_error())
940+ throw std::runtime_error(result.error().print());
941+ return result.value();
942+}
943+
944+std::vector<MediaFile> ServiceStub::listSongs(const string &artist, const string &album, const string &album_artist, int limit) const {
945+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::ListSongs, std::vector<MediaFile>>(artist, album, album_artist, (int32_t)limit);
946+ if (result.is_error())
947+ throw std::runtime_error(result.error().print());
948+ return result.value();
949+}
950+
951+std::vector<Album> ServiceStub::listAlbums(const string &artist, const string &album_artist, int limit) const {
952+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::ListAlbums, std::vector<Album>>(artist, album_artist, (int32_t)limit);
953+ if (result.is_error())
954+ throw std::runtime_error(result.error().print());
955+ return result.value();
956+}
957+std::vector<string> ServiceStub::listArtists(bool album_artists, int limit) const {
958+ auto result = p->object->invoke_method_synchronously<MediaStoreInterface::ListArtists, std::vector<string>>(album_artists, (int32_t)limit);
959+ if (result.is_error())
960+ throw std::runtime_error(result.error().print());
961+ return result.value();
962+}
963+
964+}
965+}
966
967=== added file 'src/ms-dbus/service-stub.hh'
968--- src/ms-dbus/service-stub.hh 1970-01-01 00:00:00 +0000
969+++ src/ms-dbus/service-stub.hh 2014-05-24 09:41:18 +0000
970@@ -0,0 +1,61 @@
971+/*
972+ * Copyright (C) 2013 Canonical, Ltd.
973+ *
974+ * Authors:
975+ * James Henstridge <james.henstridge@canonical.com>
976+ *
977+ * This program is free software: you can redistribute it and/or modify
978+ * it under the terms of the GNU Lesser General Public License version 3 as
979+ * published by the Free Software Foundation.
980+ *
981+ * This program is distributed in the hope that it will be useful,
982+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
983+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
984+ * GNU Lesser General Public License for more details.
985+ *
986+ * You should have received a copy of the GNU Lesser General Public License
987+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
988+ */
989+
990+#ifndef MEDIASCANNER_DBUS_SERVICE_STUB_HH
991+#define MEDIASCANNER_DBUS_SERVICE_STUB_HH
992+
993+#include <memory>
994+#include <string>
995+#include <vector>
996+#include <core/dbus/bus.h>
997+#include <core/dbus/stub.h>
998+
999+#include <mediascanner/scannercore.hh>
1000+#include "service.hh"
1001+
1002+namespace mediascanner {
1003+
1004+class Album;
1005+class MediaFile;
1006+
1007+namespace dbus {
1008+
1009+class ServiceStub : public core::dbus::Stub<MediaStoreService> {
1010+public:
1011+ ServiceStub(core::dbus::Bus::Ptr bus);
1012+ ~ServiceStub();
1013+
1014+ MediaFile lookup(const std::string &filename) const;
1015+ std::vector<MediaFile> query(const std::string &q, MediaType type, int limit=-1) const;
1016+ std::vector<Album> queryAlbums(const std::string &core_term, int limit=-1) const;
1017+ std::vector<MediaFile> getAlbumSongs(const Album& album) const;
1018+ std::string getETag(const std::string &filename) const;
1019+ std::vector<MediaFile> listSongs(const std::string& artist="", const std::string& album="", const std::string& album_artist="", int limit=-1) const;
1020+ std::vector<Album> listAlbums(const std::string& artist="", const std::string& album_artist="", int limit=-1) const;
1021+ std::vector<std::string> listArtists(bool album_artists, int limit=-1) const;
1022+
1023+private:
1024+ struct Private;
1025+ std::unique_ptr<Private> p;
1026+};
1027+
1028+}
1029+}
1030+
1031+#endif
1032
1033=== added file 'src/ms-dbus/service.hh'
1034--- src/ms-dbus/service.hh 1970-01-01 00:00:00 +0000
1035+++ src/ms-dbus/service.hh 2014-05-24 09:41:18 +0000
1036@@ -0,0 +1,62 @@
1037+/*
1038+ * Copyright (C) 2013 Canonical, Ltd.
1039+ *
1040+ * Authors:
1041+ * James Henstridge <james.henstridge@canonical.com>
1042+ *
1043+ * This program is free software: you can redistribute it and/or modify
1044+ * it under the terms of the GNU Lesser General Public License version 3 as
1045+ * published by the Free Software Foundation.
1046+ *
1047+ * This program is distributed in the hope that it will be useful,
1048+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1049+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1050+ * GNU Lesser General Public License for more details.
1051+ *
1052+ * You should have received a copy of the GNU Lesser General Public License
1053+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1054+ */
1055+
1056+#ifndef MEDIASCANNER_DBUS_SERVICE_HH
1057+#define MEDIASCANNER_DBUS_SERVICE_HH
1058+
1059+#include <core/dbus/traits/service.h>
1060+
1061+namespace mediascanner {
1062+namespace dbus {
1063+
1064+class MediaStoreService {
1065+public:
1066+ MediaStoreService() {}
1067+
1068+ MediaStoreService(const MediaStoreService&) = delete;
1069+ virtual ~MediaStoreService() = default;
1070+
1071+ MediaStoreService& operator=(const MediaStoreService&) = delete;
1072+ bool operator==(const MediaStoreService&) const = delete;
1073+};
1074+
1075+}
1076+}
1077+
1078+namespace core {
1079+namespace dbus {
1080+namespace traits {
1081+
1082+template<>
1083+struct Service<mediascanner::dbus::MediaStoreService> {
1084+ inline static const std::string& interface_name() {
1085+ static const std::string iface("com.canonical.MediaScaner2");
1086+ return iface;
1087+ }
1088+ inline static const std::string& object_path() {
1089+ static const std::string path("/com/canonical/MediaScanner2");
1090+ return path;
1091+ }
1092+};
1093+
1094+}
1095+}
1096+}
1097+
1098+#endif
1099
1100=== modified file 'src/qml/Ubuntu/MediaScanner/CMakeLists.txt'
1101--- src/qml/Ubuntu/MediaScanner/CMakeLists.txt 2014-03-24 10:04:19 +0000
1102+++ src/qml/Ubuntu/MediaScanner/CMakeLists.txt 2014-05-24 09:41:18 +0000
1103@@ -1,4 +1,5 @@
1104 include_directories(../../..)
1105+add_definitions(${DBUSCPP_CFLAGS} -DQT_NO_KEYWORDS)
1106
1107 set(QML_PLUGIN_DIR "${CMAKE_INSTALL_LIBDIR}/qt5/qml/Ubuntu/MediaScanner.0.1")
1108
1109@@ -17,7 +18,7 @@
1110
1111 set_target_properties(mediascanner-qml PROPERTIES AUTOMOC TRUE)
1112 qt5_use_modules(mediascanner-qml Qml)
1113-target_link_libraries(mediascanner-qml mediascanner)
1114+target_link_libraries(mediascanner-qml mediascanner ms-dbus)
1115
1116 install(
1117 TARGETS mediascanner-qml
1118
1119=== modified file 'src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc'
1120--- src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc 2014-02-27 08:01:05 +0000
1121+++ src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc 2014-05-24 09:41:18 +0000
1122@@ -20,10 +20,24 @@
1123 #include "MediaStoreWrapper.hh"
1124 #include <QQmlEngine>
1125
1126+#include <core/dbus/asio/executor.h>
1127+#include <ms-dbus/service-stub.hh>
1128+
1129 using namespace mediascanner::qml;
1130
1131+static core::dbus::Bus::Ptr the_session_bus() {
1132+ static core::dbus::Bus::Ptr bus = std::make_shared<core::dbus::Bus>(
1133+ core::dbus::WellKnownBus::session);
1134+ static core::dbus::Executor::Ptr executor = core::dbus::asio::make_executor(bus);
1135+ static std::once_flag once;
1136+
1137+ std::call_once(once, []() {bus->install_executor(executor);});
1138+
1139+ return bus;
1140+}
1141+
1142 MediaStoreWrapper::MediaStoreWrapper(QObject *parent)
1143- : QObject(parent), store(MS_READ_ONLY) {
1144+ : QObject(parent), store(the_session_bus()) {
1145 }
1146
1147 QList<QObject*> MediaStoreWrapper::query(const QString &q, MediaType type) {
1148
1149=== modified file 'src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.hh'
1150--- src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.hh 2014-02-27 08:01:05 +0000
1151+++ src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.hh 2014-05-24 09:41:18 +0000
1152@@ -24,10 +24,11 @@
1153 #include <QObject>
1154 #include <QString>
1155
1156-#include <mediascanner/MediaStore.hh>
1157+#include <ms-dbus/service-stub.hh>
1158 #include "MediaFileWrapper.hh"
1159
1160 namespace mediascanner {
1161+
1162 namespace qml {
1163
1164 class MediaStoreWrapper : public QObject {
1165@@ -44,7 +45,7 @@
1166 Q_INVOKABLE QList<QObject*> query(const QString &q, MediaType type);
1167 Q_INVOKABLE mediascanner::qml::MediaFileWrapper *lookup(const QString &filename);
1168
1169- mediascanner::MediaStore store;
1170+ mediascanner::dbus::ServiceStub store;
1171 };
1172
1173 }
1174
1175=== modified file 'test/CMakeLists.txt'
1176--- test/CMakeLists.txt 2014-05-02 08:53:16 +0000
1177+++ test/CMakeLists.txt 2014-05-24 09:41:18 +0000
1178@@ -17,7 +17,7 @@
1179 set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-Wno-unused-private-field")
1180 endif()
1181
1182-add_definitions(${MEDIASCANNER_CFLAGS} ${GST_CFLAGS})
1183+add_definitions(${MEDIASCANNER_CFLAGS} ${GST_CFLAGS} ${DBUSCPP_CFLAGS} -DQT_NO_KEYWORDS)
1184 include_directories(../src)
1185
1186 configure_file(test_config.h.in test_config.h)
1187@@ -43,9 +43,13 @@
1188 target_link_libraries(test_mfbuilder gtest mediascanner)
1189 add_test(test_mfbuilder test_mfbuilder)
1190
1191+add_executable(test_dbus test_dbus.cc)
1192+target_link_libraries(test_dbus gtest mediascanner ms-dbus)
1193+add_test(test_dbus test_dbus)
1194+
1195 add_executable(test_qml test_qml.cc)
1196 qt5_use_modules(test_qml QuickTest)
1197-target_link_libraries(test_qml mediascanner)
1198+target_link_libraries(test_qml mediascanner ${DBUSCPP_LDFLAGS})
1199 add_test(test_qml test_qml -input ${CMAKE_CURRENT_SOURCE_DIR}/qml -import ${CMAKE_BINARY_DIR}/src/qml)
1200 set_tests_properties(test_qml
1201 PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
1202
1203=== added file 'test/test_dbus.cc'
1204--- test/test_dbus.cc 1970-01-01 00:00:00 +0000
1205+++ test/test_dbus.cc 2014-05-24 09:41:18 +0000
1206@@ -0,0 +1,67 @@
1207+#include <gtest/gtest.h>
1208+#include <core/dbus/message.h>
1209+#include <core/dbus/object.h>
1210+#include <core/dbus/types/object_path.h>
1211+
1212+#include <mediascanner/Album.hh>
1213+#include <mediascanner/MediaFile.hh>
1214+#include <mediascanner/MediaFileBuilder.hh>
1215+#include <ms-dbus/dbus-codec.hh>
1216+
1217+class MediaStoreDBusTests : public ::testing::Test {
1218+};
1219+
1220+TEST_F(MediaStoreDBusTests, mediafile_codec) {
1221+ auto message = core::dbus::Message::make_method_call(
1222+ "org.example.Name",
1223+ core::dbus::types::ObjectPath("/org/example/Path"),
1224+ "org.example.Interface",
1225+ "Method");
1226+
1227+ mediascanner::MediaFile media = mediascanner::MediaFileBuilder("a")
1228+ .setContentType("type")
1229+ .setETag("etag")
1230+ .setDate("1900")
1231+ .setTitle("b")
1232+ .setAuthor("c")
1233+ .setAlbum("d")
1234+ .setAlbumArtist("e")
1235+ .setGenre("f")
1236+ .setDiscNumber(0)
1237+ .setTrackNumber(1)
1238+ .setDuration(5)
1239+ .setType(mediascanner::AudioMedia);
1240+ message->writer() << media;
1241+
1242+ EXPECT_EQ("(sssssssssiiii)", message->signature());
1243+ EXPECT_EQ(core::dbus::helper::TypeMapper<mediascanner::MediaFile>::signature(), message->signature());
1244+
1245+ mediascanner::MediaFile media2;
1246+ message->reader() >> media2;
1247+ EXPECT_EQ(media, media2);
1248+}
1249+
1250+TEST_F(MediaStoreDBusTests, album_codec) {
1251+ auto message = core::dbus::Message::make_method_call(
1252+ "org.example.Name",
1253+ core::dbus::types::ObjectPath("/org/example/Path"),
1254+ "org.example.Interface",
1255+ "Method");
1256+
1257+ mediascanner::Album album("title", "artist");
1258+ message->writer() << album;
1259+
1260+ EXPECT_EQ("(ss)", message->signature());
1261+ EXPECT_EQ(core::dbus::helper::TypeMapper<mediascanner::Album>::signature(), message->signature());
1262+
1263+ mediascanner::Album album2;
1264+ message->reader() >> album2;
1265+ EXPECT_EQ("title", album2.getTitle());
1266+ EXPECT_EQ("artist", album2.getArtist());
1267+ EXPECT_EQ(album, album2);
1268+}
1269+
1270+int main(int argc, char **argv) {
1271+ ::testing::InitGoogleTest(&argc, argv);
1272+ return RUN_ALL_TESTS();
1273+}
1274
1275=== modified file 'test/test_qml.cc'
1276--- test/test_qml.cc 2014-05-24 09:41:18 +0000
1277+++ test/test_qml.cc 2014-05-24 09:41:18 +0000
1278@@ -1,12 +1,19 @@
1279 #include <stdlib.h>
1280+#include <cstdio>
1281+#include <memory>
1282 #include <string>
1283
1284+#include <QProcess>
1285 #include <QtQuickTest/quicktest.h>
1286
1287+#include <core/dbus/fixture.h>
1288+
1289 #include <mediascanner/MediaStore.hh>
1290 #include <mediascanner/MediaFile.hh>
1291 #include <mediascanner/MediaFileBuilder.hh>
1292
1293+#include "test_config.h"
1294+
1295 using namespace mediascanner;
1296
1297 class MediaStoreData {
1298@@ -18,8 +25,29 @@
1299 }
1300 setenv("MEDIASCANNER_CACHEDIR", db_path.c_str(), true);
1301 populate();
1302+
1303+ // Start up private bus, and start daemon.
1304+ dbus_fixture.reset(
1305+ new core::dbus::Fixture(
1306+ core::dbus::Fixture::default_session_bus_config_file(),
1307+ core::dbus::Fixture::default_system_bus_config_file()));
1308+
1309+ daemon.setProgram(TEST_DIR "/../src/ms-dbus/mediascanner-dbus-2.0");
1310+ daemon.setProcessChannelMode(QProcess::ForwardedChannels);
1311+ daemon.start();
1312+ daemon.closeWriteChannel();
1313+ if (!daemon.waitForStarted()) {
1314+ throw std::runtime_error("Failed to start mediascanner-dbus-2.0");
1315+ }
1316 }
1317 ~MediaStoreData() {
1318+ daemon.kill();
1319+ if (!daemon.waitForFinished()) {
1320+ fprintf(stderr, "Failed to stop mediascanner-dbus-2.0\n");
1321+ }
1322+
1323+ dbus_fixture.reset();
1324+
1325 if (system("rm -rf \"$MEDIASCANNER_CACHEDIR\"") == -1) {
1326 throw std::runtime_error("rm -rf failed");
1327 }
1328@@ -126,6 +154,8 @@
1329
1330 private:
1331 std::string db_path;
1332+ std::unique_ptr<core::dbus::Fixture> dbus_fixture;
1333+ QProcess daemon;
1334 };
1335
1336 MediaStoreData data;

Subscribers

People subscribed via source and target branches