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 
38 namespace core
39 {
40 namespace dbus
41 {
42 namespace helper
43 {
44 template<>
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 
68 template<>
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 
156 namespace helper
157 {
158 template<>
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 
182 template<>
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 
196 namespace helper
197 {
198 template<>
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 
222 template<>
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 
238 namespace helper
239 {
240 template<>
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 
264 template<>
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 
278 namespace helper
279 {
280 template<>
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 
304 template<>
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 
318 namespace helper
319 {
320 template<>
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 
344 template<>
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 
358 namespace helper
359 {
360 template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType>
361 struct 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 
385 template<>
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 
411 template<core::ubuntu::media::video::detail::DimensionTag tag, typename IntegerType>
412 struct 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 
425 template<>
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 
441 namespace helper
442 {
443 template<>
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 
467 template<>
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_
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::video::detail::IntWrapper< tag, IntegerType > &in)
Definition: codec.h:414
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::Orientation &in)
Definition: codec.h:352
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 &out, core::ubuntu::media::Player::AudioStreamRole &in)
Definition: codec.h:312
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::AudioStreamRole &in)
Definition: codec.h:307
Definition: player.h:33
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::AVBackend::Backend &in)
Definition: codec.h:225
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::video::detail::IntWrapper< tag, IntegerType > &in)
Definition: codec.h:419
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::Lifetime &in)
Definition: codec.h:429
#define MH_DEBUG(...)
Definition: logger.h:123
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::PlaybackStatus &in)
Definition: codec.h:185
#define MH_WARNING(...)
Definition: logger.h:127
static void encode_argument(core::dbus::Message::Writer &writer, const core::ubuntu::media::Track::MetaData &md)
Definition: codec.h:71
static constexpr const char * TrackLengthKey
Definition: track.h:48
static void decode_argument(core::dbus::Message::Reader &out, core::ubuntu::media::Player::Error &in)
Definition: codec.h:475
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
void set_album(const std::string &album)
Definition: metadata.cpp:82
static void decode_argument(core::dbus::Message::Reader &reader, core::ubuntu::media::Track::MetaData &md)
Definition: codec.h:129
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::Player::Error &in)
Definition: codec.h:470
IntWrapper is a type-safe integer that allows for encoding/enforcing semantics by means of tags...
Definition: dimensions.h:68
static void encode_argument(core::dbus::Message::Writer &out, const core::ubuntu::media::Player::LoopStatus &in)
Definition: codec.h:267