Music Hub ..
A session-wide music playback service
codec.h
Go to the documentation of this file.
1/*
2 * Copyright © 2013-2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY {} without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 * Jim Hodapp <jim.hodapp@canonical.com>
18 */
19
20#ifndef CODEC_H_
21#define CODEC_H_
22
23#include <core/media/player.h>
24#include <core/media/track.h>
25
26#include <core/dbus/types/stl/map.h>
27#include <core/dbus/types/stl/string.h>
28#include <core/dbus/types/variant.h>
29#include <core/dbus/types/stl/vector.h>
30#include <core/dbus/codec.h>
31
32#include <boost/lexical_cast.hpp>
33
34#include "core/media/xesam.h"
35
37
38namespace core
39{
40namespace dbus
41{
42namespace helper
43{
44template<>
46{
47 constexpr static ArgumentType type_value()
48 {
49 return ArgumentType::array;
50 }
51 constexpr static bool is_basic_type()
52 {
53 return false;
54 }
55 constexpr static bool requires_signature()
56 {
57 return false;
58 }
59
60 static std::string signature()
61 {
62 static const std::string s = TypeMapper<std::map<std::string, dbus::types::Variant>>::signature();
63 return s;
64 }
65};
66}
67
68template<>
70{
71 static void encode_argument(core::dbus::Message::Writer& writer, const core::ubuntu::media::Track::MetaData& md)
72 {
73 typedef std::pair<std::string, dbus::types::Variant> Pair;
74 auto dict = writer.open_array(dbus::types::Signature
75 {dbus::helper::TypeMapper<Pair>::signature()});
76
77 for (const auto& pair : *md)
78 {
79 // The following tags are not part of the MPRIS spec and should not be encoded
80 if (pair.first == tags::Image::name or
81 pair.first == tags::PreviewImage::name)
82 continue;
83
84 auto de = dict.open_dict_entry();
85 {
87 and not pair.second.empty())
88 {
89 Codec<Pair>::encode_argument(de, std::make_pair(pair.first,
90 dbus::types::Variant::encode(
91 boost::lexical_cast<std::int64_t>(pair.second))));
92 }
93 else if (pair.first == xesam::Album::name and not pair.second.empty())
94 {
95 Codec<Pair>::encode_argument(de, std::make_pair(pair.first,
96 dbus::types::Variant::encode(pair.second)));
97 }
98 else if (pair.first == xesam::AlbumArtist::name and not pair.second.empty())
99 {
100#if 0
101 // TODO: This code doesn't work but will be needed for full MPRIS compliance.
102 // Technically there can be more than one album artist stuffed into an array.
103 // How to satisfy stuffing this data into dbus-cpp is what needs fixing.
104 auto array = de.open_array(dbus::types::Signature
105 {dbus::helper::TypeMapper<Pair>::signature()});
106 {
107 // TODO: this should really iterate over all artists, but seems
108 // we only extract one artist from playbin
109 Codec<Pair>::encode_argument(array, std::make_pair(pair.first,
110 dbus::types::Variant::encode(pair.second)));
111 }
112 de.close_array(std::move(array));
113#else
114 Codec<Pair>::encode_argument(de, std::make_pair(pair.first,
115 dbus::types::Variant::encode(pair.second)));
116#endif
117 }
118 else
119 {
120 Codec<Pair>::encode_argument(de, std::make_pair(pair.first,
121 dbus::types::Variant::encode(pair.second)));
122 }
123 }
124 dict.close_dict_entry(std::move(de));
125 }
126 writer.close_array(std::move(dict));
127 }
128
129 static void decode_argument(core::dbus::Message::Reader& reader, core::ubuntu::media::Track::MetaData& md)
130 {
131 auto array = reader.pop_array();
132
133 while (array.type() != dbus::ArgumentType::invalid)
134 {
135 auto entry = array.pop_dict_entry();
136 {
137 std::string key {entry.pop_string()};
138 auto variant = entry.pop_variant();
139 {
140 if (key == xesam::Album::name)
141 {
142 const std::string album = variant.pop_string();
143 MH_DEBUG("Getting key \"%s\" and value \"%s\"", key, album);
144 md.set_album(album);
145 }
146 else
147 {
148 MH_WARNING("Unknown metadata key \"%s\" while decoding dbus message", key);
149 }
150 }
151 }
152 }
153 }
154};
155
156namespace helper
157{
158template<>
160{
161 constexpr static ArgumentType type_value()
162 {
163 return core::dbus::ArgumentType::int16;
164 }
165 constexpr static bool is_basic_type()
166 {
167 return false;
168 }
169 constexpr static bool requires_signature()
170 {
171 return false;
172 }
173
174 static std::string signature()
175 {
176 static const std::string s = TypeMapper<std::int16_t>::signature();
177 return s;
178 }
179};
180}
181
182template<>
184{
185 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::PlaybackStatus& in)
186 {
187 out.push_int16(static_cast<std::int16_t>(in));
188 }
189
190 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::PlaybackStatus& in)
191 {
192 in = static_cast<core::ubuntu::media::Player::PlaybackStatus>(out.pop_int16());
193 }
194};
195
196namespace helper
197{
198template<>
200{
201 constexpr static ArgumentType type_value()
202 {
203 return core::dbus::ArgumentType::int16;
204 }
205 constexpr static bool is_basic_type()
206 {
207 return false;
208 }
209 constexpr static bool requires_signature()
210 {
211 return false;
212 }
213
214 static std::string signature()
215 {
216 static const std::string s = TypeMapper<std::int16_t>::signature();
217 return s;
218 }
219};
220}
221
222template<>
224{
225 static void encode_argument(core::dbus::Message::Writer& out,
227 {
228 out.push_int16(static_cast<std::int16_t>(in));
229 }
230
231 static void decode_argument(core::dbus::Message::Reader& out,
233 {
234 in = static_cast<core::ubuntu::media::AVBackend::Backend>(out.pop_int16());
235 }
236};
237
238namespace helper
239{
240template<>
242{
243 constexpr static ArgumentType type_value()
244 {
245 return core::dbus::ArgumentType::int16;
246 }
247 constexpr static bool is_basic_type()
248 {
249 return false;
250 }
251 constexpr static bool requires_signature()
252 {
253 return false;
254 }
255
256 static std::string signature()
257 {
258 static const std::string s = TypeMapper<std::int16_t>::signature();
259 return s;
260 }
261};
262}
263
264template<>
266{
267 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::LoopStatus& in)
268 {
269 out.push_int16(static_cast<std::int16_t>(in));
270 }
271
272 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::LoopStatus& in)
273 {
274 in = static_cast<core::ubuntu::media::Player::LoopStatus>(out.pop_int16());
275 }
276};
277
278namespace helper
279{
280template<>
282{
283 constexpr static ArgumentType type_value()
284 {
285 return core::dbus::ArgumentType::int16;
286 }
287 constexpr static bool is_basic_type()
288 {
289 return false;
290 }
291 constexpr static bool requires_signature()
292 {
293 return false;
294 }
295
296 static std::string signature()
297 {
298 static const std::string s = TypeMapper<std::int16_t>::signature();
299 return s;
300 }
301};
302}
303
304template<>
306{
307 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::AudioStreamRole& in)
308 {
309 out.push_int16(static_cast<std::int16_t>(in));
310 }
311
312 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::AudioStreamRole& in)
313 {
314 in = static_cast<core::ubuntu::media::Player::AudioStreamRole>(out.pop_int16());
315 }
316};
317
318namespace helper
319{
320template<>
322{
323 constexpr static ArgumentType type_value()
324 {
325 return core::dbus::ArgumentType::int16;
326 }
327 constexpr static bool is_basic_type()
328 {
329 return false;
330 }
331 constexpr static bool requires_signature()
332 {
333 return false;
334 }
335
336 static std::string signature()
337 {
338 static const std::string s = TypeMapper<std::int16_t>::signature();
339 return s;
340 }
341};
342}
343
344template<>
346{
347 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Orientation& in)
348 {
349 out.push_int16(static_cast<std::int16_t>(in));
350 }
351
352 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Orientation& in)
353 {
354 in = static_cast<core::ubuntu::media::Player::Orientation>(out.pop_int16());
355 }
356};
357
358namespace helper
359{
360template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType>
361struct TypeMapper<core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>>
362{
363 constexpr static ArgumentType type_value()
364 {
365 return core::dbus::ArgumentType::uint32;
366 }
367
368 constexpr static bool is_basic_type()
369 {
370 return true;
371 }
372
373 constexpr static bool requires_signature()
374 {
375 return false;
376 }
377
378 static std::string signature()
379 {
380 static const std::string s = TypeMapper<std::uint32_t>::signature();
381 return s;
382 }
383};
384
385template<>
387{
388 constexpr static ArgumentType type_value()
389 {
390 return core::dbus::ArgumentType::int16;
391 }
392
393 constexpr static bool is_basic_type()
394 {
395 return true;
396 }
397
398 constexpr static bool requires_signature()
399 {
400 return false;
401 }
402
403 static std::string signature()
404 {
405 static const std::string s = TypeMapper<std::int16_t>::signature();
406 return s;
407 }
408};
409}
410
411template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType>
412struct Codec<core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>>
413{
414 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::video::detail::IntWrapper<tag, IntegerType>& in)
415 {
416 out.push_uint32(in.template as<std::uint32_t>());
417 }
418
420 {
422 }
423};
424
425template<>
427{
428
429 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Lifetime& in)
430 {
431 out.push_int16(static_cast<std::int16_t>(in));
432 }
433
434
435 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Lifetime& in)
436 {
437 in = static_cast<core::ubuntu::media::Player::Lifetime>(out.pop_int16());
438 }
439};
440
441namespace helper
442{
443template<>
445{
446 constexpr static ArgumentType type_value()
447 {
448 return core::dbus::ArgumentType::int16;
449 }
450 constexpr static bool is_basic_type()
451 {
452 return false;
453 }
454 constexpr static bool requires_signature()
455 {
456 return false;
457 }
458
459 static std::string signature()
460 {
461 static const std::string s = TypeMapper<std::int16_t>::signature();
462 return s;
463 }
464};
465}
466
467template<>
469{
470 static void encode_argument(core::dbus::Message::Writer& out, const core::ubuntu::media::Player::Error& in)
471 {
472 out.push_int16(static_cast<std::int16_t>(in));
473 }
474
475 static void decode_argument(core::dbus::Message::Reader& out, core::ubuntu::media::Player::Error& in)
476 {
477 in = static_cast<core::ubuntu::media::Player::Error>(out.pop_int16());
478 }
479};
480
481}
482}
483
484#endif // CODEC_H_
void set_album(const std::string &album)
Definition: metadata.cpp:82
static constexpr const char * TrackLengthKey
Definition: track.h:48
IntWrapper is a type-safe integer that allows for encoding/enforcing semantics by means of tags.
Definition: dimensions.h:69
#define MH_WARNING(...)
Definition: logger.h:127
#define MH_DEBUG(...)
Definition: logger.h:123
Definition: player.h:34
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::AVBackend::Backend &in)
Definition: codec.h:231
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::AVBackend::Backend &in)
Definition: codec.h:225
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::AudioStreamRole &in)
Definition: codec.h:307
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::AudioStreamRole &in)
Definition: codec.h:312
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::Error &in)
Definition: codec.h:475
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::Error &in)
Definition: codec.h:470
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::Lifetime &in)
Definition: codec.h:429
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::Lifetime &in)
Definition: codec.h:435
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::LoopStatus &in)
Definition: codec.h:267
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::LoopStatus &in)
Definition: codec.h:272
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::Orientation &in)
Definition: codec.h:347
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::Orientation &in)
Definition: codec.h:352
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::PlaybackStatus &in)
Definition: codec.h:185
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::PlaybackStatus &in)
Definition: codec.h:190
static void decode_argument(core::dbus::Message::Reader &reader, core::ubuntu::media::Track::MetaData &md)
Definition: codec.h:129
static void encode_argument(core::dbus::Message::Writer &writer, const core::ubuntu::media::Track::MetaData &md)
Definition: codec.h:71
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::video::detail::IntWrapper< tag, IntegerType > &in)
Definition: codec.h:419
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::video::detail::IntWrapper< tag, IntegerType > &in)
Definition: codec.h:414