4aa28fbd325f06ce6f5a24e112ca377459bb4c67
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / dbus.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
3
4 /*
5  * Copyright 2019  Samsung Electronics Co., Ltd
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <memory>
22 #include <array>
23 #include <atomic>
24 #include <cstdint>
25 #include <map>
26 #include <sstream>
27 #include <string>
28 #include <thread>
29 #include <tuple>
30 #include <type_traits>
31 #include <unordered_map>
32 #include <vector>
33 #include <functional>
34
35 // INTERNAL INCLUDES
36 #include <dali/public-api/adaptor-framework/accessibility.h>
37 #include <dali/internal/accessibility/bridge/optional.h>
38
39 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
40 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
41
42 struct _Eina_Value;
43
44 /// \cond
45 struct ObjectPath
46 {
47   std::string value;
48 };
49
50 struct DALI_ADAPTOR_API DBusWrapper
51 {
52   virtual ~DBusWrapper() = default;
53
54   enum class ConnectionType
55   {
56     SYSTEM,
57     SESSION
58   };
59
60 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
61     struct name { virtual ~name() = default; }; \
62     using name ## Ptr = std::shared_ptr<name>; \
63     using name ## WeakPtr = std::weak_ptr<name>; \
64
65   DEFINE_TYPE(Connection, Eldbus_Connection, )
66   DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close( Value ))
67   DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
68   DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref( Value ))
69   DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
70   DEFINE_TYPE(Pending, Eldbus_Pending, )
71   DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
72
73 #undef DEFINE_TYPE
74   virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) = 0;
75
76 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
77   virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
78   virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
79 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
80   eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
81
82   eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
83   eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
84   eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
85   eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
86   eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
87   eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
88   eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
89   eldbus_message_iter_arguments_append_impl_basic(double, d)
90   eldbus_message_iter_arguments_append_impl_basic(bool, b)
91   eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
92   eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
93
94 #undef eldbus_message_iter_arguments_append_impl_basic
95 #undef eldbus_message_iter_arguments_append_impl_basic_impl
96
97   virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) = 0;
98   virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
99   virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
100   virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
101   virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
102   virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
103   virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
104
105   using SendCallback = std::function<void(const MessagePtr &msg)>;
106   virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
107   virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
108   virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
109   virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
110   virtual MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) = 0;
111   virtual MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) = 0;
112   virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) = 0;
113   virtual MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) = 0;
114   virtual MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) = 0;
115   virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
116   virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) = 0;
117   virtual ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) = 0;
118   virtual ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) = 0;
119   virtual ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) = 0;
120
121   class StringStorage
122   {
123   public:
124     struct char_ptr_deleter
125     {
126       void operator()( char* p )
127       {
128         free( p );
129       }
130     };
131     std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
132
133     const char* add( const char* txt )
134     {
135       auto ptr = strdup( txt );
136       storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
137       return storage.back().get();
138     }
139     const char* add( const std::string& txt )
140     {
141       return add( txt.c_str() );
142     }
143   };
144
145   struct CallId
146   {
147     static std::atomic< unsigned int > LastId;
148     unsigned int id = ++LastId;
149   };
150   struct MethodInfo
151   {
152     CallId id;
153     std::string memberName;
154     std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
155     std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > callback;
156   };
157   struct SignalInfo
158   {
159     CallId id;
160     std::string memberName;
161     std::vector< std::pair<std::string, std::string> > args;
162     unsigned int uniqueId;
163   };
164   struct PropertyInfo
165   {
166     CallId setterId, getterId;
167     std::string memberName, typeSignature;
168     std::function< std::string( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) > getCallback, setCallback;
169   };
170   struct SignalId
171   {
172     CallId id;
173
174     SignalId() = default;
175     SignalId( CallId id ) : id( id ) {}
176   };
177   virtual void add_interface_impl( bool fallback, const std::string& pathName,
178                               const ConnectionPtr &connection,
179                               std::vector<std::function<void()>> &destructors,
180                               const std::string& interfaceName,
181                               std::vector< MethodInfo >& dscrMethods,
182                               std::vector< PropertyInfo >& dscrProperties,
183                               std::vector< SignalInfo >& dscrSignals ) = 0;
184   virtual void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) = 0;
185   static DBusWrapper *Installed();
186   static void Install(std::unique_ptr<DBusWrapper>);
187
188   StringStorage Strings;
189 };
190
191 namespace detail {
192   enum class MethodType {
193     Method, Getter, Setter
194   };
195 }
196
197 namespace std {
198   template <> struct hash<std::tuple<std::string, std::string, std::string>> {
199     size_t operator () (const std::tuple<std::string, std::string, std::string> &a) const {
200       auto a1 = std::hash<std::string>()(std::get<0>(a));
201       auto a2 = std::hash<std::string>()(std::get<1>(a));
202       auto a3 = std::hash<std::string>()(std::get<2>(a));
203       size_t v = a1;
204       v = (v * 11400714819323198485llu) + a2;
205       v = (v * 11400714819323198485llu) + a3;
206       return v;
207     }
208   };
209   template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
210     size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType> &a) const {
211       auto a1 = std::hash<std::string>()(std::get<0>(a));
212       auto a2 = std::hash<std::string>()(std::get<1>(a));
213       auto a3 = std::hash<std::string>()(std::get<2>(a));
214       auto a4 = static_cast<size_t>(std::get<3>(a));
215       size_t v = a1;
216       v = (v * 11400714819323198485llu) + a2;
217       v = (v * 11400714819323198485llu) + a3;
218       v = (v * 11400714819323198485llu) + a4;
219       return v;
220     }
221   };
222   template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
223     size_t operator () (const std::tuple<std::string, std::string, unsigned int> &a) const {
224       auto a1 = std::hash<std::string>()(std::get<0>(a));
225       auto a2 = std::hash<std::string>()(std::get<1>(a));
226       auto a3 = std::get<2>(a);
227       size_t v = a1;
228       v = (v * 11400714819323198485llu) + a2;
229       v = (v * 11400714819323198485llu) + a3;
230       return v;
231     }
232   };
233 }
234 namespace detail {
235   template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
236   template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
237   template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
238     enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
239   };
240   template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
241   template <typename T, typename Q> struct IndexFromTypeTuple {
242     enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
243   };
244   template <typename T, typename = void> struct Encoder;
245   template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
246 }
247 struct DALI_ADAPTOR_API TestDBusWrapper : public DBusWrapper
248 {
249   using MethodType = detail::MethodType;
250   ConnectionPtr connection;
251   std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> testMethods;
252   std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> daliMethods;
253   std::unordered_map<std::tuple<std::string, std::string, unsigned int>, std::string> daliSignalsMap;
254   std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const MessagePtr&)>> daliSignals;
255   std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const _Eina_Value *)>> propertyChangeListeners;
256
257   std::vector<std::function<void()>> asyncCalls;
258
259   template <typename T> struct Variant {
260     T value;
261     Variant() = default;
262     Variant(T t) : value(std::move(t)) { }
263   };
264   template <typename ... ARGS> void Encode(const MessagePtr &m, const std::tuple<ARGS...> &args) {
265     auto iter = eldbus_message_iter_get_impl(m, true);
266     detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args);
267   }
268   template <typename ... ARGS> void Decode(const MessagePtr &m, std::tuple<ARGS...> &args) {
269     auto iter = eldbus_message_iter_get_impl(m, false);
270     detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(*this, args, iter);
271   }
272   MessagePtr newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply);
273   MessagePtr newReplyMessage(const MessagePtr &m);
274
275   template <typename ... ARGS> void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple<ARGS...> &args) {
276     if (path.empty()) throw error{};
277     if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
278     auto msg = newMessage(path, interface, name, false);
279     Encode(msg, args);
280     auto it = daliSignals.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
281     if (it == daliSignals.end()) throw error{};
282     it->second(msg);
283   }
284   static std::shared_ptr<_Eina_Value> createEinaValue(bool);
285   template <typename T> void fromTestChangeProperty(std::string path, const std::string &interface, const std::string &name, T new_value) {
286     auto v = createEinaValue(new_value);
287     if (path.empty()) throw error{};
288     if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
289     auto it = propertyChangeListeners.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
290     if (it == propertyChangeListeners.end()) throw error{};
291     it->second(v.get());
292   }
293   template <typename ... ARGS1, typename ... ARGS2> std::tuple<ARGS1...> fromTestCall(const std::string &path, const std::string &interface, const std::string &name, const std::tuple<ARGS2...> &args) {
294     auto msg = newMessage(path, interface, name, false);
295     Encode(msg, args);
296     auto res = call(daliMethods, "daliMethods", msg, MethodType::Method);
297     std::string a, b;
298     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
299     std::tuple<ARGS1...> tmp;
300     Decode(res, tmp);
301     return tmp;
302   }
303   template <typename T> T fromTestGet(const std::string &path, const std::string &interface, const std::string &name) {
304     auto msg = newMessage(path, interface, name, false);
305     auto res = call(daliMethods, "daliMethods", msg, MethodType::Getter);
306     std::string a, b;
307     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
308     std::tuple<T> tmp;
309     Decode(res, tmp);
310     return std::move(std::get<0>(tmp));
311   }
312   template <typename ... ARGS1, typename T> std::tuple<ARGS1...> fromTestSet(const std::string &path, const std::string &interface, const std::string &name, const T &arg) {
313     auto msg = newMessage(path, interface, name, false);
314     Encode(msg, TestDBusWrapper::Variant<T>{ arg });
315     auto res = call(daliMethods, "daliMethods", msg, MethodType::Setter);
316     std::string a, b;
317     if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
318     std::tuple<ARGS1...> tmp;
319     Decode(res, tmp);
320     return tmp;
321   }
322
323   TestDBusWrapper();
324   ~TestDBusWrapper();
325
326   class error : public std::exception {
327     std::shared_ptr<std::ostringstream> temp = std::make_shared<std::ostringstream>();
328     mutable std::string text;
329   public:
330     error() = default;
331
332     template <typename T> error &operator << (T &&t) {
333       *temp << std::forward<T>(t);
334       return *this;
335     }
336     const char *what() const noexcept override {
337       text = temp->str();
338       return text.c_str();
339     }
340   };
341   #define DEFINE_TYPE(name) struct name ## Impl; static name ## Impl *get(const name ## Ptr &);
342   DEFINE_TYPE(Connection)
343   DEFINE_TYPE(Proxy)
344   DEFINE_TYPE(Object)
345   DEFINE_TYPE(Message)
346   DEFINE_TYPE(MessageIter)
347   #undef DEFINE_TYPE
348
349   class Element;
350   using ElementList = std::list<Element>;
351   using ElementMap = std::map<std::string, std::string>;
352   using ElementTuple = std::tuple<
353     uint8_t, uint16_t, uint32_t, uint64_t, int16_t, int32_t, int64_t, double, bool, std::string, ObjectPath,
354     ElementList
355   >;
356
357   class Element {
358     ElementTuple data;
359     char signature_ = 0, end_ = 0, index_ = 0;
360     template <typename T> void set(T &&t, char signature = detail::DBusSig<T>::value) {
361       signature_ = signature;
362       end_ = detail::DBusSig<T>::end;
363       index_ = static_cast<char>(detail::IndexFromTypeTuple<ElementTuple, T>::value);
364       get<T>() = std::forward<T>(t);
365     }
366   public:
367     template <typename T> Element(T &&t, typename std::enable_if<detail::DBusSig<T>::value != 0>::type* = nullptr) { set(std::forward<T>(t)); }
368     Element(ElementList t, int signature) { set(std::move(t), static_cast<char>(signature)); }
369
370     char signature() const { return signature_; }
371     char end() const { return end_; }
372     char index() const { return index_; }
373     bool isContainer() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, ElementList>::value; }
374     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
375     bool is() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, T>::value; }
376     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
377     const T &get() const { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
378     template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
379     T &get() { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
380   };
381
382   ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) override;
383
384 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
385   void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) override; \
386   bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) override;
387 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
388   eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
389
390   eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
391   eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
392   eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
393   eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
394   eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
395   eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
396   eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
397   eldbus_message_iter_arguments_append_impl_basic(double, d)
398   eldbus_message_iter_arguments_append_impl_basic(bool, b)
399   eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
400   eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
401
402 #undef eldbus_message_iter_arguments_append_impl_basic
403 #undef eldbus_message_iter_arguments_append_impl_basic_impl
404
405   MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override;
406   MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
407   MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
408   MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
409   MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
410   bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
411   std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
412   PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
413   std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
414   void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
415   std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
416   MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override;
417   MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override;
418   PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override;
419   MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override;
420   MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override;
421   ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override;
422   std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override;
423   ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override;
424   ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override;
425   ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override;
426   void add_property_changed_event_listener_impl( const ProxyPtr &proxy, const std::string &interface, const std::string &name, std::function< void( const _Eina_Value * ) > cb) override;
427   void add_interface_impl( bool fallback, const std::string& pathName,
428                               const ConnectionPtr &connection,
429                               std::vector<std::function<void()>> &destructors,
430                               const std::string& interfaceName,
431                               std::vector< MethodInfo >& dscrMethods,
432                               std::vector< PropertyInfo >& dscrProperties,
433                               std::vector< SignalInfo >& dscrSignals ) override;
434   static bool completed(const MessageIterPtr &iter);
435 private:
436   MessagePtr call(std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> &mp, const std::string &name, const MessagePtr &msg, MethodType type);
437 };
438
439 namespace detail {
440   template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
441   template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
442   template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
443   template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
444   template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
445   template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
446   template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
447   template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
448   template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
449   template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
450   template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
451   template <> struct DBusSigImpl<TestDBusWrapper::ElementList> { enum { value = '(', end = ')' }; };
452   template <> struct DBusSigImpl<TestDBusWrapper::ElementMap> { enum { value = '{', end = '}' }; };
453
454   template <typename T> struct Encoder<T, decltype(TestDBusWrapper().eldbus_message_iter_arguments_append_impl(TestDBusWrapper::MessageIterPtr(), T()))> {
455     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
456       w.eldbus_message_iter_arguments_append_impl(tgt, src);
457     }
458     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
459       if (!w.eldbus_message_iter_get_and_next_impl(src, tgt)) throw TestDBusWrapper::error{};
460     }
461   };
462   template <typename T> struct Encoder<T, typename std::enable_if<std::is_enum<T>::value>::type> {
463     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
464       Encoder<typename std::underlying_type<T>::type>::encode(w, tgt, static_cast<typename std::underlying_type<T>::type>(src));
465     }
466     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
467       typename std::underlying_type<T>::type v = 0;
468       Encoder<typename std::underlying_type<T>::type>::decode(w, v, src);
469       tgt = static_cast<T>(v);
470     }
471   };
472   template <typename T> struct Encoder<const T> {
473     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
474       Encoder<T>::encode(w, tgt, src);
475     }
476     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
477       Encoder<T>::decode(w, tgt, src);
478     }
479   };
480   template <typename T> struct Encoder<const T &> {
481     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
482       Encoder<T>::encode(w, tgt, src);
483     }
484     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
485       Encoder<T>::decode(w, tgt, src);
486     }
487   };
488   template <typename T> struct Encoder<T &> {
489     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
490       Encoder<T>::encode(w, tgt, src);
491     }
492     static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
493       Encoder<T>::decode(w, tgt, src);
494     }
495   };
496   template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple {
497     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
498       Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::encode(w, tgt, std::get<I>(src));
499       EncoderTuple<I + 1, S, ARGS...>::encode(w, tgt, src);
500     }
501     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
502       Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::decode(w, std::get<I>(tgt), src);
503       EncoderTuple<I + 1, S, ARGS...>::decode(w, tgt, src);
504     }
505   };
506   template <size_t S, typename ... ARGS> struct EncoderTuple<S, S, ARGS...> {
507     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) { }
508     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) { }
509   };
510   template <typename ...ARGS> struct Encoder<std::tuple<ARGS...>> {
511     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
512       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'r', "");
513       EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(w, var, src);
514     }
515     static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
516       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'r' );
517       if( !s ) throw TestDBusWrapper::error{};
518       EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(w, tgt, s);
519     }
520   };
521   template <typename A, typename B> struct Encoder<std::pair<A, B>> {
522     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair<A, B> &src, char type = 'r') {
523       auto var = w.eldbus_message_iter_container_new_impl( tgt, type, "");
524       Encoder<A>::encode(w, var, src.first);
525       Encoder<B>::encode(w, var, src.second);
526     }
527     static void decode(TestDBusWrapper &w, std::pair<A, B> &tgt, const TestDBusWrapper::MessageIterPtr &src, char type = 'r') {
528       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, type );
529       if( !s ) throw TestDBusWrapper::error{};
530       Encoder<A>::decode(w, tgt.first, s);
531       Encoder<B>::decode(w, tgt.second, s);
532     }
533   };
534   template <typename T> struct Encoder<TestDBusWrapper::Variant<T>> {
535     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant<T> &src) {
536       //w.eldbus_message_iter_arguments_append_impl(tgt, src);
537       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', "");
538       Encoder<T>::encode(w, var, src.value);
539     }
540     static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
541       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'v' );
542       if( !s ) throw TestDBusWrapper::error{};
543       Encoder<T>::decode(w, tgt.value, s);
544     }
545   };
546   template <typename T> struct Encoder<std::vector<T>> {
547     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector<T> &src) {
548       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
549       for(auto &q : src)
550         Encoder<T>::encode(w, var, q);
551     }
552     static void decode(TestDBusWrapper &w, std::vector<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
553       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
554       if( !s ) throw TestDBusWrapper::error{};
555       while(!TestDBusWrapper::completed(s)) {
556         tgt.push_back({});
557         Encoder<T>::decode(w, tgt.back(), s);
558       }
559     }
560   };
561   template <typename K, typename V> struct Encoder<std::unordered_map<K,V>> {
562     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map<K,V> &src) {
563       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
564       for(auto &q : src){
565         Encoder<typename std::unordered_map<K,V>::value_type>::encode(w, var, q, 'e');
566       }
567     }
568     static void decode(TestDBusWrapper &w, std::unordered_map<K,V> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
569       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
570       if( !s ) throw TestDBusWrapper::error{};
571       while(!TestDBusWrapper::completed(s)) {
572         std::pair<K, V> tmp;
573         Encoder<std::pair<K,V>>::decode(w, tmp, s, 'e');
574         tgt.insert(std::move(tmp));
575       }
576     }
577   };
578   template <typename T, size_t I> struct Encoder<std::array<T, I>> {
579     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array<T, I> &src) {
580       auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
581       for(auto &q : src)
582         Encoder<T>::encode(w, var, q);
583     }
584     static void decode(TestDBusWrapper &w, std::array<T, I> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
585       auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
586       if( !s ) throw TestDBusWrapper::error{};
587       size_t i = 0;
588       while(!TestDBusWrapper::completed(s)) {
589         if(i >= tgt.size()) throw TestDBusWrapper::error{};
590         Encoder<T>::decode(w, tgt[i], s);
591         ++i;
592       }
593       if( i!=tgt.size()) throw TestDBusWrapper::error{};
594     }
595   };
596   template <> struct Encoder<Dali::Accessibility::Address> {
597     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) {
598       Encoder<std::tuple<std::string, ObjectPath>>::encode(w, tgt,std::tuple<std::string, ObjectPath> {
599         src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } }
600       );
601     }
602     static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) {
603       std::tuple<std::string, ObjectPath> tmp;
604       Encoder<std::tuple<std::string, ObjectPath>>::decode(w, tmp, src);
605       static const size_t prefixSize = std::string{ "/org/a11y/atspi/accessible/" }.size();
606       tgt = { std::move(std::get<0>(tmp)), std::get<1>(tmp).value.substr(prefixSize) };
607     }
608   };
609   template <> struct Encoder<const char*> {
610     static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) {
611       Encoder<std::string>::encode(w, tgt, src);
612     }
613   };
614 }
615 /// \endcond
616
617 #define DBUS_DEBUG( ... )                                \
618   do                                                     \
619   {                                                      \
620     DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
621   } while( 0 )
622
623 #define DBUS_W DBusWrapper::Installed()
624
625 /**
626  * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
627  *
628  * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
629  * when using eldbus from C++.
630  *
631  * The library:
632  * - takes care of marshalling arguments to and from DBUS calls.
633  * - allows synchronous and asynchronous calls.
634  * - allows synchronous and asynchronous listeners on signals.
635  * - manages all involved objects' lifetimes.
636  * - errors are passed as optional-alike objects, no exceptions are used.
637  * - allows setting additional debug-print function for more details about
638  *   what's going on
639  *
640  * DBUS's method signatures (and expected return values) are specified as template argument,
641  * using functor syntax. For example:
642  * \code{.cpp}
643  * auto dbus = DBusClient{ ... };
644  * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
645  * \endcode
646  * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
647  * of types float, float and string (float will be automatically converted to double).
648  * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
649  * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
650  * Slightly different (asynchronous) example:
651  * \code{.cpp}
652  * auto dbus = DBusClient{ ... };
653  * std::function<void(ValueOrError<int, float>)> callback;
654  * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
655  * \endcode
656  * Now the call takes the same arguments and has the same signature. But expected values are different -
657  * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
658  * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
659  * you need to pass a callback, which will be called either with received data and error message.
660  *
661  * Library is not thread-safe, the same object shouldn't be called from different threads without
662  * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
663  */
664 namespace DBus
665 {
666 /// \cond
667 class DBusServer;
668 class DBusClient;
669 class DBusInterfaceDescription;
670
671 /**
672  * @brief Formats debug message and calls debug printer (if any) with it
673  */
674 void debugPrint( const char* file, size_t line, const char* format, ... );
675
676 /**
677  * @brief Sets debug printer callback, which will be called with debug messages
678  *
679  * Callback will be called in various moments of DBus activity. First value passed to callback
680  * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
681  * user can safely printf it.
682  */
683 void setDebugPrinter( std::function< void( const char*, size_t ) > );
684
685 struct Error
686 {
687   std::string message;
688
689   Error() = default;
690   Error( std::string msg ) : message( std::move( msg ) )
691   {
692     assert( !message.empty() );
693   }
694 };
695
696 struct Success
697 {
698 };
699 /// \endcond
700
701 /**
702  * @brief Value representing data, that came from DBUS or error message
703  *
704  * Object of this class either helds series of values (of types ARGS...)
705  * or error message. This object will be true in boolean context, if has data
706  * and false, if an error occured.
707  * It's valid to create ValueOrError object with empty argument list or void:
708  * \code{.cpp}
709  * ValueOrError<> v1;
710  * ValueOrError<void> v2;
711  * \endcode
712  * Both mean the same - ValueOrError containing no real data and being a marker,
713  * wherever operation successed or failed and containing possible error message.
714  */
715 template < typename... ARGS >
716 class ValueOrError
717 {
718 public:
719   /**
720    * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
721    */
722   ValueOrError() = default;
723
724   /**
725    * @brief Value constructor.
726    *
727    * This will be initialized as success with passed in values.
728    */
729   ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
730
731   /**
732    * @brief Alternative Value constructor.
733    *
734    * This will be initialized as success with passed in values.
735    */
736   ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
737
738   /**
739    * @brief Error constructor. This will be initialized as failure with given error message.
740    */
741   ValueOrError( Error e ) : error( std::move( e ) )
742   {
743     assert( !error.message.empty() );
744   }
745
746   /**
747    * @brief bool operator.
748    *
749    * Returns true, if operation was successful (getValues member is callable), or false
750    * when operation failed (getError is callable).
751    */
752   explicit operator bool() const
753   {
754     return error.message.empty();
755   }
756
757   /**
758    * @brief Returns error message object.
759    *
760    * Returns object containing error message associated with the failed operation.
761    * Only callable, if operation actually failed, otherwise will assert.
762    */
763   const Error& getError() const
764   {
765     return error;
766   }
767
768   /**
769    * @brief Returns modifiable tuple of held data.
770    *
771    * Returns reference to the internal tuple containing held data.
772    * User can modify (or move) data safely.
773    * Only callable, if operation actually successed, otherwise will assert.
774    */
775   std::tuple< ARGS... >& getValues()
776   {
777     assert( *this );
778     return value;
779   }
780
781   /**
782    * @brief Returns const tuple of held data.
783    *
784    * Returns const reference to the internal tuple containing held data.
785    * Only callable, if operation actually successed, otherwise will assert.
786    */
787   const std::tuple< ARGS... >& getValues() const
788   {
789     assert( *this );
790     return value;
791   }
792
793 protected:
794   /// \cond
795   std::tuple< ARGS... > value;
796   Error error;
797   /// \endcond
798 };
799
800 /// \cond
801 template <>
802 class ValueOrError<>
803 {
804 public:
805   ValueOrError() = default;
806   ValueOrError( std::tuple<> t ) {}
807   ValueOrError( Error e ) : error( std::move( e ) )
808   {
809     assert( !error.message.empty() );
810   }
811
812   explicit operator bool() const
813   {
814     return error.message.empty();
815   }
816   const Error& getError() const
817   {
818     return error;
819   }
820   std::tuple<>& getValues()
821   {
822     assert( *this );
823     static std::tuple<> t;
824     return t;
825   }
826   std::tuple<> getValues() const
827   {
828     assert( *this );
829     return {};
830   }
831
832 protected:
833   Error error;
834 };
835
836 template <>
837 class ValueOrError< void >
838 {
839 public:
840   ValueOrError() = default;
841   ValueOrError( Success ) {}
842   ValueOrError( Error e ) : error( std::move( e ) )
843   {
844     assert( !error.message.empty() );
845   }
846
847   explicit operator bool() const
848   {
849     return error.message.empty();
850   }
851   const Error& getError() const
852   {
853     return error;
854   }
855   std::tuple<>& getValues()
856   {
857     assert( *this );
858     static std::tuple<> t;
859     return t;
860   }
861   std::tuple<> getValues() const
862   {
863     assert( *this );
864     return {};
865   }
866
867 protected:
868   Error error;
869 };
870
871 using ObjectPath = ObjectPath;
872
873 /// \endcond
874
875 /**
876  * @brief Class used to marshall DBUS's variant type
877  *
878  * Minimalistic class, that allows user to specify DBUS variant type
879  * as argument or return value. You need to pass real type hidden under variant as
880  * template type \b A. At this point library doesn't allow to expected one of few classes
881  * as return data in variant. So for example user can't specify method call, which on return
882  * expects DBUS variant holding either string or int.
883  */
884 template < typename A >
885 struct EldbusVariant
886 {
887   A value;
888 };
889
890 /**
891  * @brief Namespace for private, internal functions and classes
892  */
893 namespace detail
894 {
895 /// \cond
896 template < typename T, typename = void >
897 struct signature;
898 template < typename... ARGS >
899 struct signature< std::tuple< ARGS... > >;
900 template < typename A, typename B >
901 struct signature< std::pair< A, B > >;
902 template < typename A >
903 struct signature< std::vector< A > >;
904 template < typename A, size_t N >
905 struct signature< std::array< A, N > >;
906 template < typename A, typename B >
907 struct signature< std::unordered_map< A, B > >;
908 template < typename A, typename B >
909 struct signature< std::map< A, B > >;
910 /// \endcond
911
912 /**
913  * @brief Signature class for marshalling uint8 type.
914  */
915 template <>
916 struct signature< uint8_t >
917 {
918   /**
919    * @brief Returns name of type marshalled, for informative purposes
920    */
921   static std::string name()
922   {
923     return "uint8_t";
924   }
925
926   /**
927    * @brief Returns DBUS' signature of type marshalled
928    */
929   static std::string sig()
930   {
931     return "y";
932   }
933
934   /**
935    * @brief Marshals value v as marshalled type into message
936    */
937   static void set( const DBusWrapper::MessageIterPtr &iter, uint8_t v )
938   {
939     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
940   }
941
942   /**
943    * @brief Marshals value from marshalled type into variable v
944    */
945   static bool get( const DBusWrapper::MessageIterPtr &iter, uint8_t& v )
946   {
947     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
948   }
949 };
950
951 /**
952  * @brief Signature class for marshalling uint16 type.
953  */
954 template <>
955 struct signature< uint16_t >
956 {
957   /**
958    * @brief Returns name of type marshalled, for informative purposes
959    */
960   static std::string name()
961   {
962     return "uint16_t";
963   }
964
965   /**
966    * @brief Returns DBUS' signature of type marshalled
967    */
968   static std::string sig()
969   {
970     return "q";
971   }
972
973   /**
974    * @brief Marshals value v as marshalled type into message
975    */
976   static void set( const DBusWrapper::MessageIterPtr &iter, uint16_t v )
977   {
978     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
979   }
980
981   /**
982    * @brief Marshals value from marshalled type into variable v
983    */
984   static bool get( const DBusWrapper::MessageIterPtr &iter, uint16_t& v )
985   {
986     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
987   }
988 };
989
990 /**
991  * @brief Signature class for marshalling uint32 type.
992  */
993 template <>
994 struct signature< uint32_t >
995 {
996   /**
997    * @brief Returns name of type marshalled, for informative purposes
998    */
999   static std::string name()
1000   {
1001     return "uint32_t";
1002   }
1003
1004   /**
1005    * @brief Returns DBUS' signature of type marshalled
1006    */
1007   static std::string sig()
1008   {
1009     return "u";
1010   }
1011
1012   /**
1013    * @brief Marshals value v as marshalled type into message
1014    */
1015   static void set( const DBusWrapper::MessageIterPtr &iter, uint32_t v )
1016   {
1017     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1018   }
1019
1020   /**
1021    * @brief Marshals value from marshalled type into variable v
1022    */
1023   static bool get( const DBusWrapper::MessageIterPtr &iter, uint32_t& v )
1024   {
1025     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1026   }
1027 };
1028
1029 /**
1030  * @brief Signature class for marshalling uint64 type.
1031  */
1032 template <>
1033 struct signature< uint64_t >
1034 {
1035   /**
1036    * @brief Returns name of type marshalled, for informative purposes
1037    */
1038   static std::string name()
1039   {
1040     return "uint64_t";
1041   }
1042
1043   /**
1044    * @brief Returns DBUS' signature of type marshalled
1045    */
1046   static std::string sig()
1047   {
1048     return "t";
1049   }
1050
1051   /**
1052    * @brief Marshals value v as marshalled type into message
1053    */
1054   static void set( const DBusWrapper::MessageIterPtr &iter, uint64_t v )
1055   {
1056     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1057   }
1058
1059   /**
1060    * @brief Marshals value from marshalled type into variable v
1061    */
1062   static bool get( const DBusWrapper::MessageIterPtr &iter, uint64_t& v )
1063   {
1064     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1065   }
1066 };
1067
1068 /**
1069  * @brief Signature class for marshalling int16 type.
1070  */
1071 template <>
1072 struct signature< int16_t >
1073 {
1074   /**
1075    * @brief Returns name of type marshalled, for informative purposes
1076    */
1077   static std::string name()
1078   {
1079     return "int16_t";
1080   }
1081
1082   /**
1083    * @brief Returns DBUS' signature of type marshalled
1084    */
1085   static std::string sig()
1086   {
1087     return "n";
1088   }
1089
1090   /**
1091    * @brief Marshals value v as marshalled type into message
1092    */
1093   static void set( const DBusWrapper::MessageIterPtr &iter, int16_t v )
1094   {
1095     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1096   }
1097
1098   /**
1099    * @brief Marshals value from marshalled type into variable v
1100    */
1101   static bool get( const DBusWrapper::MessageIterPtr &iter, int16_t& v )
1102   {
1103     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1104   }
1105 };
1106
1107 /**
1108  * @brief Signature class for marshalling int32 type.
1109  */
1110 template <>
1111 struct signature< int32_t >
1112 {
1113   /**
1114    * @brief Returns name of type marshalled, for informative purposes
1115    */
1116   static std::string name()
1117   {
1118     return "int32_t";
1119   }
1120
1121   /**
1122    * @brief Returns DBUS' signature of type marshalled
1123    */
1124   static std::string sig()
1125   {
1126     return "i";
1127   }
1128
1129   /**
1130    * @brief Marshals value v as marshalled type into message
1131    */
1132   static void set( const DBusWrapper::MessageIterPtr &iter, int32_t v )
1133   {
1134     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1135   }
1136
1137   /**
1138    * @brief Marshals value from marshalled type into variable v
1139    */
1140   static bool get( const DBusWrapper::MessageIterPtr &iter, int32_t& v )
1141   {
1142     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1143   }
1144 };
1145
1146 /**
1147  * @brief Signature class for marshalling int64 type.
1148  */
1149 template <>
1150 struct signature< int64_t >
1151 {
1152   /**
1153    * @brief Returns name of type marshalled, for informative purposes
1154    */
1155   static std::string name()
1156   {
1157     return "int64_t";
1158   }
1159
1160   /**
1161    * @brief Returns DBUS' signature of type marshalled
1162    */
1163   static std::string sig()
1164   {
1165     return "x";
1166   }
1167
1168   /**
1169    * @brief Marshals value v as marshalled type into message
1170    */
1171   static void set( const DBusWrapper::MessageIterPtr &iter, int64_t v )
1172   {
1173     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1174   }
1175
1176   /**
1177    * @brief Marshals value from marshalled type into variable v
1178    */
1179   static bool get( const DBusWrapper::MessageIterPtr &iter, int64_t& v )
1180   {
1181     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1182   }
1183 };
1184
1185 /**
1186  * @brief Signature class for marshalling double type.
1187  */
1188 template <>
1189 struct signature< double >
1190 {
1191   /**
1192    * @brief Returns name of type marshalled, for informative purposes
1193    */
1194   static std::string name()
1195   {
1196     return "double";
1197   }
1198
1199   /**
1200    * @brief Returns DBUS' signature of type marshalled
1201    */
1202   static std::string sig()
1203   {
1204     return "d";
1205   }
1206
1207   /**
1208    * @brief Marshals value v as marshalled type into message
1209    */
1210   static void set( const DBusWrapper::MessageIterPtr &iter, double v )
1211   {
1212     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1213   }
1214
1215   /**
1216    * @brief Marshals value from marshalled type into variable v
1217    */
1218   static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1219   {
1220     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1221   }
1222
1223   /**
1224    * @brief Marshals value from marshalled type into variable v
1225    */
1226   static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1227   {
1228     double v = 0;
1229     auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1230     v2 = static_cast< float >( v );
1231     return r;
1232   }
1233 };
1234
1235 /**
1236  * @brief Signature class for marshalling float type.
1237  */
1238 template <>
1239 struct signature< float >
1240 {
1241   /**
1242    * @brief Returns name of type marshalled, for informative purposes
1243    */
1244   static std::string name()
1245   {
1246     return "float";
1247   }
1248
1249   /**
1250    * @brief Returns DBUS' signature of type marshalled
1251    */
1252   static std::string sig()
1253   {
1254     return "d";
1255   }
1256
1257   /**
1258    * @brief Marshals value v as marshalled type into message
1259    */
1260   static void set( const DBusWrapper::MessageIterPtr &iter, float v )
1261   {
1262     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1263   }
1264
1265   /**
1266    * @brief Marshals value from marshalled type into variable v
1267    */
1268   static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1269   {
1270     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1271   }
1272
1273   /**
1274    * @brief Marshals value from marshalled type into variable v
1275    */
1276   static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1277   {
1278     double v = 0;
1279     auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1280     v2 = static_cast< float >( v );
1281     return r;
1282   }
1283 };
1284
1285 /**
1286  * @brief Signature class for marshalling boolean type.
1287  */
1288 template <>
1289 struct signature< bool >
1290 {
1291   /**
1292    * @brief Returns name of type marshalled, for informative purposes
1293    */
1294   static std::string name()
1295   {
1296     return "bool";
1297   }
1298
1299   /**
1300    * @brief Returns DBUS' signature of type marshalled
1301    */
1302   static std::string sig()
1303   {
1304     return "b";
1305   }
1306
1307   /**
1308    * @brief Marshals value v as marshalled type into message
1309    */
1310   static void set( const DBusWrapper::MessageIterPtr &iter, bool v )
1311   {
1312     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1313   }
1314
1315   /**
1316    * @brief Marshals value from marshalled type into variable v
1317    */
1318   static bool get( const DBusWrapper::MessageIterPtr &iter, bool& v )
1319   {
1320     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1321   }
1322 };
1323
1324 template < typename T >
1325 struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
1326 {
1327   /**
1328    * @brief Returns name of type marshalled, for informative purposes
1329    */
1330   static std::string name()
1331   {
1332     return "enum";
1333   }
1334
1335   /**
1336    * @brief Returns DBUS' signature of type marshalled
1337    */
1338   static std::string sig()
1339   {
1340     return signature<typename std::underlying_type<T>::type>::sig();
1341   }
1342
1343   /**
1344    * @brief Marshals value v as marshalled type into message
1345    */
1346   static void set( const DBusWrapper::MessageIterPtr &iter, T v )
1347   {
1348     signature<typename std::underlying_type<T>::type>::set(iter, static_cast< int64_t >( v ));
1349   }
1350
1351   /**
1352    * @brief Marshals value from marshalled type into variable v
1353    */
1354   static bool get( const DBusWrapper::MessageIterPtr &iter, T& v )
1355   {
1356     typename std::underlying_type<T>::type q = 0;
1357     if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
1358       return false;
1359
1360     v = static_cast< T >( q );
1361     return true;
1362   }
1363 };
1364
1365 /**
1366  * @brief Signature class for marshalling string type.
1367  *
1368  * Both (const) char * and std::string types are accepted as value to send.
1369  * Only std::string is accepted as value to receive.
1370  */
1371 template <>
1372 struct signature< std::string >
1373 {
1374   /**
1375    * @brief Returns name of type marshalled, for informative purposes
1376    */
1377   static std::string name()
1378   {
1379     return "string";
1380   }
1381
1382   /**
1383    * @brief Returns DBUS' signature of type marshalled
1384    */
1385   static std::string sig()
1386   {
1387     return "s";
1388   }
1389
1390   /**
1391    * @brief Marshals value v as marshalled type into message
1392    */
1393   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1394   {
1395     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1396   }
1397
1398 // /**
1399 //  * @brief Marshals value v as marshalled type into message
1400 //  */
1401 //  static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1402 //  {
1403 //    DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1404 //  }
1405
1406   /**
1407    * @brief Marshals value from marshalled type into variable v
1408    */
1409   static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1410   {
1411     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1412   }
1413 };
1414
1415 template <>
1416 struct signature< ObjectPath >
1417 {
1418   /**
1419    * @brief Returns name of type marshalled, for informative purposes
1420    */
1421   static std::string name()
1422   {
1423     return "path";
1424   }
1425
1426   /**
1427    * @brief Returns DBUS' signature of type marshalled
1428    */
1429   static std::string sig()
1430   {
1431     return "o";
1432   }
1433
1434   /**
1435    * @brief Marshals value v as marshalled type into message
1436    */
1437   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1438   {
1439     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1440   }
1441
1442   /**
1443    * @brief Marshals value v as marshalled type into message
1444    */
1445   static void set( const DBusWrapper::MessageIterPtr &iter, const ObjectPath& v )
1446   {
1447     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1448   }
1449
1450   /**
1451    * @brief Marshals value v as marshalled type into message
1452    */
1453   static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1454   {
1455     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1456   }
1457
1458   /**
1459    * @brief Marshals value from marshalled type into variable v
1460    */
1461   static bool get( const DBusWrapper::MessageIterPtr &iter, ObjectPath& v )
1462   {
1463     return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1464   }
1465
1466   /**
1467    * @brief Marshals value from marshalled type into variable v
1468    */
1469   static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1470   {
1471     ObjectPath q;
1472     if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1473     v = std::move(q.value);
1474     return true;
1475   }
1476 };
1477
1478 /**
1479  * @brief Signature class for marshalling (const) char * type.
1480  *
1481  * Both (const) char * and std::string types are accepted as value to send.
1482  * You can't use (const) char * variable type to receive value.
1483  */
1484 template <>
1485 struct signature< char* >
1486 {
1487   /**
1488    * @brief Returns name of type marshalled, for informative purposes
1489    */
1490   static std::string name()
1491   {
1492     return "string";
1493   }
1494
1495   /**
1496    * @brief Returns DBUS' signature of type marshalled
1497    */
1498   static std::string sig()
1499   {
1500     return "s";
1501   }
1502
1503   /**
1504    * @brief Marshals value v as marshalled type into message
1505    */
1506   static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1507   {
1508     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1509   }
1510
1511   /**
1512    * @brief Marshals value v as marshalled type into message
1513    */
1514   static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1515   {
1516     DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1517   }
1518 };
1519 /// \cond
1520
1521 template < size_t INDEX, typename A, typename... ARGS >
1522 struct signature_tuple_element_type_helper
1523 {
1524   using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1525 };
1526
1527 template < typename A, typename... ARGS >
1528 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1529 {
1530   using type = A;
1531 };
1532 /// \endcond
1533
1534 /**
1535  * @brief Helper class to marshall tuples
1536  *
1537  * This class marshals all elements of the tuple value starting at the index INDEX
1538  * and incrementing. This class recursively calls itself with increasing INDEX value
1539  * until INDEX is equal to SIZE, where recursive calling ends.
1540  */
1541 template < size_t INDEX, size_t SIZE, typename... ARGS >
1542 struct signature_tuple_helper
1543 {
1544   using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1545
1546   /**
1547    * @brief Returns name of type marshalled, for informative purposes
1548    */
1549   static std::string name()
1550   {
1551     if( INDEX + 1 >= SIZE )
1552       return signature< current_type >::name();
1553     return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
1554   }
1555
1556   /**
1557    * @brief Returns DBUS' signature of type marshalled
1558    */
1559   static std::string sig()
1560   {
1561     return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1562   }
1563
1564   /**
1565    * @brief Marshals value v as marshalled type into message
1566    */
1567   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1568   {
1569     signature< current_type >::set( iter, std::get< INDEX >( args ) );
1570     signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
1571   }
1572
1573   /**
1574    * @brief Marshals value from marshalled type into variable v
1575    */
1576   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1577   {
1578     return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
1579            signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
1580   }
1581 };
1582
1583 /**
1584  * @brief Helper class to marshall tuples
1585  *
1586  * This class marks end of the tuple marshalling. Members of this class are called
1587  * when INDEX value is equal to SIZE.
1588  */
1589 template < size_t SIZE, typename... ARGS >
1590 struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1591 {
1592   /**
1593    * @brief Returns name of type marshalled, for informative purposes
1594    */
1595   static std::string name()
1596   {
1597     return "";
1598   }
1599
1600   /**
1601    * @brief Returns DBUS' signature of type marshalled
1602    */
1603   static std::string sig()
1604   {
1605     return "";
1606   }
1607
1608   /**
1609    * @brief Marshals value v as marshalled type into message
1610    */
1611   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1612   {
1613   }
1614
1615   /**
1616    * @brief Marshals value from marshalled type into variable v
1617    */
1618   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1619   {
1620     return true;
1621   }
1622 };
1623
1624 /**
1625  * @brief Signature class for marshalling tuple of values
1626  *
1627  * This class marshalls tuple of values. This represents
1628  * DBUS struct typle, encoded with character 'r'
1629  */
1630 template < typename... ARGS >
1631 struct signature< std::tuple< ARGS... > >
1632 {
1633   /**
1634    * @brief Returns name of type marshalled, for informative purposes
1635    */
1636   static std::string name()
1637   {
1638     return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1639   }
1640
1641   /**
1642    * @brief Returns DBUS' signature of type marshalled
1643    */
1644   static std::string sig()
1645   {
1646     return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
1647   }
1648
1649   /**
1650    * @brief Marshals value v as marshalled type into message
1651    */
1652   static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1653   {
1654     auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'r', "");
1655     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
1656   }
1657
1658   /**
1659    * @brief Marshals value from marshalled type into variable v
1660    */
1661   static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1662   {
1663     auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1664     if (!entry) return false;
1665     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
1666   }
1667 };
1668
1669 /**
1670  * @brief Signature class for marshalling ValueOrError template type
1671  *
1672  * ValueOrError template type is used to marshall list of values passed to
1673  * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1674  * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1675  * While (ss(s)) is represented as
1676  * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1677  * or
1678  * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1679  */
1680 template < typename... ARGS >
1681 struct signature< ValueOrError< ARGS... > >
1682 {
1683   /**
1684    * @brief Returns name of type marshalled, for informative purposes
1685    */
1686   static std::string name()
1687   {
1688     return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1689   }
1690
1691   /**
1692    * @brief Returns DBUS' signature of type marshalled
1693    */
1694   static std::string sig()
1695   {
1696     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
1697   }
1698
1699   /**
1700    * @brief Marshals value v as marshalled type into message
1701    */
1702   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< ARGS... >& args )
1703   {
1704     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
1705   }
1706
1707   /**
1708    * @brief Marshals value from marshalled type into variable v
1709    */
1710   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< ARGS... >& args )
1711   {
1712     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
1713   }
1714 };
1715
1716 /**
1717  * @brief Signature class for marshalling ValueOrError<void> type
1718  */
1719 template <>
1720 struct signature< ValueOrError< void > >
1721 {
1722   /**
1723    * @brief Returns name of type marshalled, for informative purposes
1724    */
1725   static std::string name()
1726   {
1727     return "ValueOrError<void>";
1728   }
1729
1730   /**
1731    * @brief Returns DBUS' signature of type marshalled
1732    */
1733   static std::string sig()
1734   {
1735     return "";
1736   }
1737
1738   /**
1739    * @brief Marshals value v as marshalled type into message
1740    */
1741   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< void >& args )
1742   {
1743   }
1744
1745   /**
1746    * @brief Marshals value from marshalled type into variable v
1747    */
1748   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< void >& args )
1749   {
1750     return true;
1751   }
1752 };
1753
1754 /**
1755  * @brief Signature class for marshalling ValueOrError<> type
1756  */
1757 template <>
1758 struct signature< ValueOrError<> >
1759 {
1760   /**
1761    * @brief Returns name of type marshalled, for informative purposes
1762    */
1763   static std::string name()
1764   {
1765     return "ValueOrError<>";
1766   }
1767
1768   /**
1769    * @brief Returns DBUS' signature of type marshalled
1770    */
1771   static std::string sig()
1772   {
1773     return "";
1774   }
1775
1776   /**
1777    * @brief Marshals value v as marshalled type into message
1778    */
1779   static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError<>& args )
1780   {
1781   }
1782
1783   /**
1784    * @brief Marshals value from marshalled type into variable v
1785    */
1786   static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError<>& args )
1787   {
1788     return true;
1789   }
1790 };
1791
1792 /**
1793  * @brief Signature class for marshalling pair of types
1794  */
1795 template < typename A, typename B >
1796 struct signature< std::pair< A, B > >
1797 {
1798   /**
1799    * @brief Returns name of type marshalled, for informative purposes
1800    */
1801   static std::string name()
1802   {
1803     return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1804   }
1805
1806   /**
1807    * @brief Returns DBUS' signature of type marshalled
1808    */
1809   static std::string sig()
1810   {
1811     return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1812   }
1813
1814   /**
1815    * @brief Marshals value v as marshalled type into message
1816    */
1817   static void set( const DBusWrapper::MessageIterPtr &iter, const std::pair< A, B >& ab, bool dictionary = false )
1818   {
1819     auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, dictionary ? 'e' : 'r', "");
1820     signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
1821   }
1822
1823   /**
1824    * @brief Marshals value from marshalled type into variable v
1825    */
1826   static bool get( const DBusWrapper::MessageIterPtr &iter, std::pair< A, B >& ab )
1827   {
1828     auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1829     if (!entry) {
1830       entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, '{' );
1831       if (!entry) return false;
1832     }
1833
1834     std::tuple< A, B > ab_tmp;
1835     auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
1836     if( z )
1837     {
1838       ab.first = std::move( std::get< 0 >( ab_tmp ) );
1839       ab.second = std::move( std::get< 1 >( ab_tmp ) );
1840     }
1841     return z;
1842   }
1843 };
1844
1845 /**
1846  * @brief Signature class for marshalling std::vector template type
1847  *
1848  * This marshals container's content as DBUS a ascii character type code.
1849  */
1850 template < typename A >
1851 struct signature< std::vector< A > >
1852 {
1853   /**
1854    * @brief Returns name of type marshalled, for informative purposes
1855    */
1856   static std::string name()
1857   {
1858     return "vector<" + signature< A >::name() + ">";
1859   }
1860
1861   /**
1862    * @brief Returns DBUS' signature of type marshalled
1863    */
1864   static std::string sig()
1865   {
1866     return "a" + signature< A >::sig();
1867   }
1868
1869   /**
1870    * @brief Marshals value v as marshalled type into message
1871    */
1872   static void set( const DBusWrapper::MessageIterPtr &iter, const std::vector< A >& v )
1873   {
1874     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1875     assert( lst );
1876     for( auto& a : v )
1877     {
1878       signature< A >::set( lst, a );
1879     }
1880   }
1881
1882   /**
1883    * @brief Marshals value from marshalled type into variable v
1884    */
1885   static bool get( const DBusWrapper::MessageIterPtr &iter, std::vector< A >& v )
1886   {
1887     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1888     if (!s) return false;
1889     v.clear();
1890     A a;
1891     while( signature< A >::get( s, a ) )
1892       v.push_back( std::move( a ) );
1893
1894     return true;
1895   }
1896 };
1897
1898 /**
1899  * @brief Signature class for marshalling std::array template type
1900  *
1901  * This marshals container's content as DBUS a ascii character type code.
1902  */
1903 template < typename A, size_t N >
1904 struct signature< std::array< A, N > >
1905 {
1906   /**
1907    * @brief Returns name of type marshalled, for informative purposes
1908    */
1909   static std::string name()
1910   {
1911     return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
1912   }
1913
1914   /**
1915    * @brief Returns DBUS' signature of type marshalled
1916    */
1917   static std::string sig()
1918   {
1919     return "a" + signature< A >::sig();
1920   }
1921
1922   /**
1923    * @brief Marshals value v as marshalled type into message
1924    */
1925   static void set( const DBusWrapper::MessageIterPtr &iter, const std::array< A, N >& v )
1926   {
1927     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1928     assert( lst );
1929     for( auto& a : v )
1930     {
1931       signature< A >::set( lst, a );
1932     }
1933   }
1934
1935   /**
1936    * @brief Marshals value from marshalled type into variable v
1937    */
1938   static bool get( const DBusWrapper::MessageIterPtr &iter, std::array< A, N >& v )
1939   {
1940     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1941     if ( !s )
1942       return false;
1943     for( auto& a : v )
1944     {
1945       if( !signature< A >::get( s, a ) )
1946         return false;
1947     }
1948     return true;
1949   }
1950 };
1951
1952 /**
1953  * @brief Signature class for marshalling EldbusVariant type
1954  *
1955  * This marshals variant's content as DBUS v ascii character type code.
1956  */
1957 template < typename A >
1958 struct signature< EldbusVariant< A > >
1959 {
1960   /**
1961    * @brief Returns name of type marshalled, for informative purposes
1962    */
1963   static std::string name()
1964   {
1965     return "variant<" + signature< A >::name() + ">";
1966   }
1967
1968   /**
1969    * @brief Returns DBUS' signature of type marshalled
1970    */
1971   static std::string sig()
1972   {
1973     return "v";
1974   }
1975
1976   /**
1977    * @brief Marshals value v as marshalled type into message
1978    */
1979   static void set( const DBusWrapper::MessageIterPtr &iter, const EldbusVariant< A >& v )
1980   {
1981     set( iter, v.value );
1982   }
1983
1984   /**
1985    * @brief Marshals value v as marshalled type into message
1986    */
1987   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
1988   {
1989     auto var = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'v', signature< A >::sig());
1990     signature< A >::set( var, v );
1991   }
1992
1993   /**
1994    * @brief Marshals value from marshalled type into variable v
1995    */
1996   static bool get( const DBusWrapper::MessageIterPtr &iter, EldbusVariant< A >& v )
1997   {
1998     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'v' );
1999     if( !s )
2000       return false;
2001     return signature< A >::get( s, v.value );
2002   }
2003 };
2004
2005 /**
2006  * @brief Signature class for marshalling std::unordered_map template type
2007  *
2008  * This marshals container's content as DBUS {} ascii character type code.
2009  * Note, that library doesnt check, if the key is basic type, as DBUS
2010  * specification mandates.
2011  * User can always exchange std::unordered_map for std::map and the reverse.
2012  * User can receive such values as std::vector of std::pair<key, value> values.
2013  * Order of such values is unspecified.
2014  */
2015 template < typename A, typename B >
2016 struct signature< std::unordered_map< A, B > >
2017 {
2018   /**
2019    * @brief Returns name of type marshalled, for informative purposes
2020    */
2021   static std::string name()
2022   {
2023     return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2024   }
2025
2026   /**
2027    * @brief Returns DBUS' signature of type marshalled
2028    */
2029   static std::string sig()
2030   {
2031     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2032   }
2033
2034   /**
2035    * @brief Marshals value v as marshalled type into message
2036    */
2037   static void set( const DBusWrapper::MessageIterPtr &iter, const std::unordered_map< A, B >& v )
2038   {
2039     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2040     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2041     assert( lst );
2042     for( auto& a : v )
2043     {
2044       signature< std::pair< A, B > >::set( lst, a, true );
2045     }
2046   }
2047
2048   /**
2049    * @brief Marshals value from marshalled type into variable v
2050    */
2051   static bool get( const DBusWrapper::MessageIterPtr &iter, std::unordered_map< A, B >& v )
2052   {
2053     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2054     v.clear();
2055     if( !s )
2056       return false;
2057     std::pair< A, B > a;
2058     while( signature< std::pair< A, B > >::get( s, a ) )
2059       v.insert( std::move( a ) );
2060     return true;
2061   }
2062 };
2063
2064 /**
2065  * @brief Signature class for marshalling std::unordered_map template type
2066  *
2067  * This marshals container's content as DBUS {} ascii character type code.
2068  * Note, that library doesnt check, if the key is basic type, as DBUS
2069  * specification mandates.
2070  * User can always exchange std::unordered_map for std::map and the reverse.
2071  * User can receive such values as std::vector of std::pair<key, value> values.
2072  * Order of such values is unspecified.
2073  */
2074 template < typename A, typename B >
2075 struct signature< std::map< A, B > >
2076 {
2077   /**
2078    * @brief Returns name of type marshalled, for informative purposes
2079    */
2080   static std::string name()
2081   {
2082     return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2083   }
2084
2085   /**
2086    * @brief Returns DBUS' signature of type marshalled
2087    */
2088   static std::string sig()
2089   {
2090     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2091   }
2092
2093   /**
2094    * @brief Marshals value v as marshalled type into message
2095    */
2096   static void set( const DBusWrapper::MessageIterPtr &iter, const std::map< A, B >& v )
2097   {
2098     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2099     auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2100     assert( lst );
2101     for( auto& a : v )
2102     {
2103       signature< std::pair< A, B > >::set( lst, a, true );
2104     }
2105   }
2106
2107   /**
2108    * @brief Marshals value from marshalled type into variable v
2109    */
2110   static bool get( const DBusWrapper::MessageIterPtr &iter, std::map< A, B >& v )
2111   {
2112     auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2113     if( !s )
2114       return false;
2115     std::pair< A, B > a;
2116     while( signature< std::pair< A, B > >::get( s, a ) )
2117       v.insert( std::move( a ) );
2118     return true;
2119   }
2120 };
2121
2122 /**
2123  * @brief Signature helper class for marshalling const reference types
2124  */
2125 template < typename A >
2126 struct signature< const A& >
2127 {
2128   /**
2129    * @brief Returns name of type marshalled, for informative purposes
2130    */
2131   static std::string name()
2132   {
2133     return "const " + signature< A >::name() + "&";
2134   }
2135
2136   /**
2137    * @brief Returns DBUS' signature of type marshalled
2138    */
2139   static std::string sig()
2140   {
2141     return signature< A >::sig();
2142   }
2143
2144   /**
2145    * @brief Marshals value v as marshalled type into message
2146    */
2147   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2148   {
2149     signature< A >::set( iter, v );
2150   }
2151
2152   /**
2153    * @brief Marshals value from marshalled type into variable v
2154    */
2155   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2156   {
2157     signature< A >::get( iter, v );
2158   }
2159 };
2160
2161 /**
2162  * @brief Signature helper class for marshalling reference types
2163  */
2164 template < typename A >
2165 struct signature< A& >
2166 {
2167   /**
2168    * @brief Returns name of type marshalled, for informative purposes
2169    */
2170   static std::string name()
2171   {
2172     return signature< A >::name() + "&";
2173   }
2174
2175   /**
2176    * @brief Returns DBUS' signature of type marshalled
2177    */
2178   static std::string sig()
2179   {
2180     return signature< A >::sig();
2181   }
2182
2183   /**
2184    * @brief Marshals value v as marshalled type into message
2185    */
2186   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2187   {
2188     signature< A >::set( iter, v );
2189   }
2190
2191   /**
2192    * @brief Marshals value from marshalled type into variable v
2193    */
2194   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2195   {
2196     signature< A >::get( iter, v );
2197   }
2198 };
2199
2200 /**
2201  * @brief Signature helper class for marshalling const types
2202  */
2203 template < typename A >
2204 struct signature< const A >
2205 {
2206   /**
2207    * @brief Returns name of type marshalled, for informative purposes
2208    */
2209   static std::string name()
2210   {
2211     return "const " + signature< A >::name();
2212   }
2213
2214   /**
2215    * @brief Returns DBUS' signature of type marshalled
2216    */
2217   static std::string sig()
2218   {
2219     return signature< A >::sig();
2220   }
2221
2222   /**
2223    * @brief Marshals value v as marshalled type into message
2224    */
2225   static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2226   {
2227     signature< A >::set( iter, v );
2228   }
2229
2230   /**
2231    * @brief Marshals value from marshalled type into variable v
2232    */
2233   static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2234   {
2235     signature< A >::get( iter, v );
2236   }
2237 };
2238
2239 /// \cond
2240 using CallId = DBusWrapper::CallId;
2241
2242 template < typename ValueType >
2243 ValueType unpackValues( CallId callId, const DBusWrapper::MessagePtr &msg )
2244 {
2245   auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, false );
2246   ValueType r;
2247
2248   if( iter )
2249   {
2250     if( !signature< ValueType >::get( iter, r ) )
2251     {
2252       DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
2253       r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
2254                 DBUS_W->eldbus_message_signature_get_impl( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
2255     }
2256   }
2257   else
2258   {
2259     r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
2260   }
2261   return r;
2262 }
2263
2264 inline void packValues_helper( const DBusWrapper::MessageIterPtr& ) {}
2265
2266 template < typename A, typename... ARGS >
2267 void packValues_helper( const DBusWrapper::MessageIterPtr &iter, A&& a, ARGS&&... r )
2268 {
2269   signature< A >::set( iter, std::forward< A >( a ) );
2270   packValues_helper( iter, std::forward< ARGS >( r )... );
2271 }
2272
2273 template < typename... ARGS >
2274 void packValues( CallId callId, const DBusWrapper::MessagePtr &msg, ARGS&&... r )
2275 {
2276   auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, true );
2277   packValues_helper( iter, std::forward< ARGS >( r )... );
2278 }
2279
2280 template < typename >
2281 struct ReturnType;
2282 template < typename R, typename... ARGS >
2283 struct ReturnType< R( ARGS... ) >
2284 {
2285   using type = R;
2286 };
2287
2288 template < typename R, typename... ARGS >
2289 struct ReturnType< std::function< R( ARGS... ) > >
2290 {
2291   using type = R;
2292 };
2293
2294 template < int... >
2295 struct sequence
2296 {
2297 };
2298
2299 template < int N, int... S >
2300 struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
2301 {
2302 };
2303
2304 template < int... S >
2305 struct sequence_gen< 0, S... >
2306 {
2307   typedef sequence< S... > type;
2308 };
2309
2310 template < typename C, typename... ARGS >
2311 struct apply_helper
2312 {
2313   const std::function< C >& c;
2314   const std::tuple< ARGS... >& args;
2315
2316   template < int... S >
2317   auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
2318   {
2319     return c( std::get< S >( args )... );
2320   }
2321   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2322   {
2323     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2324   }
2325 };
2326
2327 template < typename C, typename A, typename... ARGS >
2328 struct apply_helper_2
2329 {
2330   const std::function< C >& c;
2331   const A& a;
2332   const std::tuple< ARGS... >& args;
2333
2334   template < int... S >
2335   auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
2336   {
2337     return c( a, std::get< S >( args )... );
2338   }
2339   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2340   {
2341     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2342   }
2343 };
2344
2345 template < typename C, typename... ARGS >
2346 auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2347 {
2348   apply_helper< C, ARGS... > ah{c, args};
2349   return ah.apply_1();
2350 }
2351
2352 template < typename C, typename D, typename... ARGS >
2353 auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2354 {
2355   apply_helper_2< C, D, ARGS... > ah{c, d, args};
2356   return ah.apply_1();
2357 }
2358
2359 struct ConnectionState
2360 {
2361   DBusWrapper::ConnectionPtr connection;
2362   DBusWrapper::ObjectPtr object;
2363   DBusWrapper::ProxyPtr proxy, propertiesProxy;
2364 };
2365
2366 template < typename RETTYPE, typename... ARGS >
2367 RETTYPE call( CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
2368 {
2369   const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2370   if( !proxy )
2371   {
2372     DBUS_DEBUG( "call %d: not initialized", callId.id );
2373     return Error{"not initialized"};
2374   }
2375
2376   DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
2377   auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2378   if( !msg )
2379   {
2380     DBUS_DEBUG( "call %d: failed", callId.id );
2381     return Error{"failed to create message"};
2382   }
2383
2384   detail::packValues( callId, msg, args... );
2385   auto reply = DBUS_W->eldbus_proxy_send_and_block_impl( proxy, msg );
2386   DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
2387   if( !reply )
2388   {
2389     DBUS_DEBUG( "call %d: failed", callId.id );
2390     return Error{"eldbus returned null as reply"};
2391   }
2392   std::string errname, errmsg;
2393   if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2394   {
2395     DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2396     return Error{errname + ": " + errmsg};
2397   }
2398   DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2399     DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2400   return detail::unpackValues< RETTYPE >( callId, reply );
2401 }
2402
2403 template < typename RETTYPE, typename... ARGS >
2404 void asyncCall( CallId callId, const ConnectionState &connectionState,
2405                 bool property, const std::string& funcName,
2406                 std::function< void( RETTYPE ) > callback, const ARGS&... args )
2407 {
2408   const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2409   if( !proxy )
2410   {
2411     DBUS_DEBUG( "call %d: not initialized", callId.id );
2412     callback( Error{"not initialized"} );
2413     return;
2414   }
2415
2416   auto msg = DBUS_W->eldbus_proxy_method_call_new_impl( proxy, funcName );
2417   if( !msg )
2418   {
2419     DBUS_DEBUG( "call %d: failed", callId.id );
2420     callback( Error{"failed to create message"} );
2421     return;
2422   }
2423
2424   detail::packValues( callId, msg, args... );
2425   auto pending = DBUS_W->eldbus_proxy_send_impl( proxy, msg, [callback, callId, proxy]( const DBusWrapper::MessagePtr &reply ) {
2426         DBUS_DEBUG( "call %d: calling done", callId.id );
2427         if( !reply )
2428         {
2429           DBUS_DEBUG( "call %d: failed", callId.id );
2430           callback( Error{"eldbus returned null as reply"} );
2431         }
2432         else
2433         {
2434           std::string errname, errmsg;
2435           if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2436           {
2437             DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2438             callback( Error{errname + ": " + errmsg} );
2439           }
2440           else
2441           {
2442             DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2443                 DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2444             callback( detail::unpackValues< RETTYPE >( callId, reply ) );
2445           }
2446         }
2447       }
2448     );
2449   if( pending )
2450   {
2451     DBUS_DEBUG( "call %d: call sent", callId.id );
2452   }
2453   else
2454   {
2455     DBUS_DEBUG( "call %d: failed to send call", callId.id );
2456     callback( Error{"failed to send call"} );
2457   }
2458 }
2459
2460 inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2461 {
2462   DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2463 }
2464
2465 inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2466 {
2467   DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2468 }
2469
2470 inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2471                                           const std::string& propertyName )
2472 {
2473   DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
2474 }
2475
2476 using StringStorage = DBusWrapper::StringStorage;
2477
2478 template < typename A, typename... ARGS >
2479 struct EldbusArgGenerator_Helper
2480 {
2481   static void add( std::vector< std::pair<std::string, std::string> >& r )
2482   {
2483     auto s = r.size();
2484     auto sig = signature< A >::sig();
2485     assert( !sig.empty() );
2486     auto name = "p" + std::to_string( s + 1 );
2487     r.push_back({ std::move(sig), std::move(name) });
2488     EldbusArgGenerator_Helper<ARGS...>::add( r );
2489   }
2490 };
2491
2492 template <>
2493 struct EldbusArgGenerator_Helper< void >
2494 {
2495   static void add( std::vector< std::pair<std::string, std::string> >& )
2496   {
2497   }
2498 };
2499
2500 template <>
2501 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2502 {
2503   static void add( std::vector< std::pair<std::string, std::string> >& )
2504   {
2505   }
2506 };
2507 template <>
2508 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2509 {
2510   static void add( std::vector< std::pair<std::string, std::string> >& )
2511   {
2512   }
2513 };
2514
2515 template < typename... ARGS >
2516 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2517 {
2518   static void add( std::vector< std::pair<std::string, std::string> >& r )
2519   {
2520     EldbusArgGenerator_Helper< ARGS..., void >::add( r );
2521   }
2522 };
2523
2524 template < typename RetType >
2525 struct dbus_interface_return_type_traits
2526 {
2527   using type = ValueOrError< RetType >;
2528 };
2529
2530 template < typename... ARGS >
2531 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2532 {
2533   using type = ValueOrError< ARGS... >;
2534 };
2535
2536 template < typename T >
2537 struct dbus_interface_traits;
2538 template < typename RetType, typename... ARGS >
2539 struct dbus_interface_traits< RetType( ARGS... ) >
2540 {
2541   using Ret = typename dbus_interface_return_type_traits< RetType >::type;
2542   using SyncCB = std::function< Ret( ARGS... ) >;
2543   using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
2544   using VEArgs = ValueOrError< ARGS... >;
2545 };
2546
2547 template < typename T >
2548 struct EldbusArgGenerator_Args;
2549 template < typename RetType, typename... ARGS >
2550 struct EldbusArgGenerator_Args< RetType( ARGS... ) >
2551 {
2552   static std::string name()
2553   {
2554     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
2555   }
2556   static std::vector< std::pair<std::string, std::string> > get()
2557   {
2558     std::vector< std::pair<std::string, std::string> > tmp;
2559     EldbusArgGenerator_Helper< ARGS..., void >::add( tmp );
2560     return tmp;
2561   }
2562 };
2563
2564 template < typename T >
2565 struct EldbusArgGenerator_ReturnType;
2566 template < typename RetType, typename... ARGS >
2567 struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
2568 {
2569   static std::string name()
2570   {
2571     return signature< RetType >::name();
2572   }
2573   static std::vector< std::pair<std::string, std::string> > get( )
2574   {
2575     std::vector< std::pair<std::string, std::string> > tmp;
2576     EldbusArgGenerator_Helper< RetType, void >::add( tmp );
2577     return tmp;
2578   }
2579 };
2580
2581 template < typename T >
2582 struct EldbusArgGenerator_ReturnType;
2583 template < typename... ARGS >
2584 struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
2585 {
2586   static std::string name()
2587   {
2588     return "";
2589   }
2590   static std::vector< std::pair<std::string, std::string> > get( )
2591   {
2592     return {};
2593   }
2594 };
2595 /// \endcond
2596 }
2597
2598 using ConnectionType = DBusWrapper::ConnectionType;
2599
2600 /**
2601  * @brief Class representing client's end of DBUS connection
2602  *
2603  * Allows calling (synchronous and asynchronos) methods on selected interface
2604  * Allows (synchronous and asynchronos) setting / getting properties.
2605  * Allows registering signals.
2606  */
2607 class DBusClient
2608 {
2609   /// \cond
2610   struct ConnectionInfo
2611   {
2612     std::string interfaceName, busName, pathName;
2613   };
2614   /// \endcond
2615 public:
2616   /**
2617    * @brief Default constructor, creates non-connected object.
2618    */
2619   DBusClient() = default;
2620
2621   /**
2622    * @brief Connects to dbus choosen by tp, using given arguments
2623    *
2624    * @param bus_name name of the bus to connect to
2625    * @param path_name object's path
2626    * @param interface_name interface name
2627    */
2628   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2629               ConnectionType tp );
2630
2631   /**
2632    * @brief Connects to dbus using connection conn
2633    *
2634    * @param bus_name name of the bus to connect to
2635    * @param path_name object's path
2636    * @param interface_name interface name
2637    * @param conn connection object from getDBusConnectionByType call
2638    */
2639   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2640               const DBusWrapper::ConnectionPtr &conn = {} );
2641
2642   /**
2643    * @brief Destructor object.
2644    *
2645    * All signals added will be disconnected.
2646    * All asynchronous calls will be cancelled, their callback's will be called
2647    * with failure message.
2648    */
2649   ~DBusClient() = default;
2650   DBusClient( const DBusClient& ) = delete;
2651   DBusClient( DBusClient&& ) = default;
2652
2653   DBusClient& operator=( DBusClient&& ) = default;
2654   DBusClient& operator=( const DBusClient& ) = delete;
2655
2656   /**
2657    * @brief bool operator
2658    *
2659    * Returns true, if object is connected to DBUS
2660    */
2661   explicit operator bool() const
2662   {
2663     return bool( connectionState->proxy );
2664   }
2665
2666   /**
2667    * @brief Helper class for calling a method
2668    *
2669    * Template type T defines both arguments sent to the method
2670    * and expected values. Receiving different values will be reported as
2671    * error. For example:
2672    * \code{.cpp} Method<int(float, float)> \endcode
2673    * defines method, which takes two arguments (two floats) and return
2674    * single value of type int.
2675    */
2676   template < typename T >
2677   struct Method
2678   {
2679     /// \cond
2680     using RetType = typename detail::dbus_interface_traits< T >::Ret;
2681     const detail::ConnectionState &connectionState;
2682     std::string funcName;
2683     std::string info;
2684     std::shared_ptr< ConnectionInfo > connectionInfo;
2685     /// \endcond
2686
2687     /**
2688      * @brief Executes synchronous call on DBUS's method
2689      *
2690      * The function returns ValueOrError<...> object, which
2691      * contains either received values or error message.
2692      *
2693      * @param args arguments to pass to the method
2694      */
2695     template < typename... ARGS >
2696     RetType call( const ARGS&... args )
2697     {
2698       detail::CallId callId;
2699       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2700       return detail::call< RetType >( callId, connectionState, false, funcName, args... );
2701     }
2702
2703     /**
2704      * @brief Executes asynchronous call on DBUS's method
2705      *
2706      * The function calls callback with either received values or error message.
2707      *
2708      * @param callback callback functor, which will be called with return value(s) or error message
2709      * @param args arguments to pass to the method
2710      */
2711     template < typename... ARGS >
2712     void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
2713     {
2714       detail::CallId callId;
2715       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2716       detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
2717     }
2718   };
2719
2720   /**
2721    * @brief Helper class for calling a property
2722    *
2723    * Template type T defines type of the value hidden under property.
2724    * Note, that library automatically wraps both sent and received value into
2725    * DBUS's wrapper type.
2726    */
2727   template < typename T >
2728   struct Property
2729   {
2730     /// \cond
2731     using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
2732     using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
2733     const detail::ConnectionState &connectionState;
2734     std::string propName;
2735     std::string info;
2736     std::shared_ptr< ConnectionInfo > connectionInfo;
2737     /// \endcond
2738
2739     /**
2740      * @brief executes synchronous get on property
2741      *
2742      * The function returns ValueOrError<...> object, which
2743      * contains either received values or error message.
2744      */
2745     RetType get()
2746     {
2747       detail::CallId callId;
2748       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2749       auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
2750       if( !z )
2751         return z.getError();
2752       return {std::get< 0 >( z.getValues() ).value};
2753     }
2754
2755     /**
2756      * @brief executes asynchronous get on property
2757      *
2758      * The function calls callback with either received values or error message.
2759      *
2760      * @param callback callback functor, which will be called with return value(s) or error message
2761      */
2762     void asyncGet( std::function< void( RetType ) > callback )
2763     {
2764       detail::CallId callId;
2765       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2766       auto cc = [callback]( VariantRetType reply ) {
2767         if( reply )
2768           callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
2769         else
2770           callback( reply.getError() );
2771       };
2772       detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
2773     }
2774
2775     /**
2776      * @brief executes synchronous set on property
2777      *
2778      * The function returns ValueOrError<void> object, with
2779      * possible error message.
2780      */
2781     ValueOrError< void > set( const T& r )
2782     {
2783       detail::CallId callId;
2784       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2785       EldbusVariant< T > variantValue{std::move( r )};
2786       return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
2787     }
2788
2789     /**
2790      * @brief executes asynchronous get on property
2791      *
2792      * The function calls callback with either received values or error message.
2793      *
2794      * @param callback callback functor, which will be called with return value(s) or error message
2795      */
2796     void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
2797     {
2798       detail::CallId callId;
2799       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2800       EldbusVariant< T > variantValue{std::move( r )};
2801       detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
2802     }
2803   };
2804
2805   /**
2806    * @brief Constructs Property<...> object for calling properties
2807    *
2808    * The function constructs and returns proxy object for calling property.
2809    *
2810    * @param propName property name to set and / or query
2811    */
2812   template < typename PropertyType >
2813   Property< PropertyType > property( std::string propName )
2814   {
2815     return Property< PropertyType >{*connectionState, std::move( propName ), info, connectionInfo};
2816   }
2817
2818   /**
2819    * @brief Constructs Method<...> object for calling methods
2820    *
2821    * The function constructs and returns proxy object for calling method.
2822    *
2823    * @param funcName function name to call
2824    */
2825   template < typename MethodType >
2826   Method< MethodType > method( std::string funcName )
2827   {
2828     return Method< MethodType >{*connectionState, std::move( funcName ), info, connectionInfo};
2829   }
2830
2831   /**
2832    * @brief Registers notification callback, when property has changed
2833    *
2834    * The callback will be called with new value, when property's value has changed.
2835    * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2836    * there's no check for this.
2837    */
2838   template < typename V >
2839   void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
2840   {
2841     detail::CallId callId;
2842     detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
2843     DBUS_DEBUG( "call %d: adding property", callId.id );
2844     auto &cI = this->connectionInfo;
2845     DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
2846       [callback]( const _Eina_Value *newValue ) {
2847       V val = 0;
2848       if( !getFromEinaValue( newValue, &val ) )
2849       {
2850         DBUS_DEBUG( "unable to get property's value" );
2851         return;
2852       }
2853       callback( val );
2854     });
2855   }
2856
2857   /**
2858    * @brief Registers callback on the DBUS' signal
2859    *
2860    * The function registers callback signalName. When signal comes, callback will be called.
2861    * Callback object will exists as long as signal is registered. You can unregister signal
2862    * by destroying DBusClient object.
2863    *
2864    * @param signalName name of the signal to register
2865    * @param callback callback to call
2866    */
2867   template < typename SignalType >
2868   void addSignal( std::string signalName, std::function< SignalType > callback )
2869   {
2870     detail::CallId callId;
2871     detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
2872     DBUS_W->eldbus_proxy_signal_handler_add_impl( connectionState->proxy, signalName,
2873       [callId, callback, signalName]( const DBusWrapper::MessagePtr &msg ) -> void {
2874         std::string errname, aux;
2875         if( DBUS_W->eldbus_message_error_get_impl( msg, errname, aux ) )
2876         {
2877           DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str() );
2878           return;
2879         }
2880         DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl( msg ).c_str() );
2881         using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2882         auto params = detail::unpackValues< ParamsType >( callId, msg );
2883         if( !params )
2884         {
2885           DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
2886           return;
2887         }
2888         try
2889         {
2890           detail::apply( callback, params.getValues() );
2891         }
2892         catch( ... )
2893         {
2894           DBUS_DEBUG( "unhandled exception" );
2895           assert( 0 );
2896         }
2897       });
2898   }
2899
2900 private:
2901   /// \cond
2902   std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2903   std::string info;
2904   std::shared_ptr< ConnectionInfo > connectionInfo;
2905
2906   static bool getFromEinaValue(const _Eina_Value *v, void *dst);
2907   /// \endcond
2908 };
2909
2910 /**
2911  * @brief Helper class describing DBUS's server interface
2912  *
2913  */
2914 class DBusInterfaceDescription
2915 {
2916   friend class DBusServer;
2917
2918 public:
2919   /// \cond
2920   using MethodInfo = DBusWrapper::MethodInfo;
2921   using SignalInfo = DBusWrapper::SignalInfo;
2922   using PropertyInfo = DBusWrapper::PropertyInfo;
2923   using SignalId = DBusWrapper::SignalId;
2924   /// \endcond
2925
2926   /**
2927    * @brief Creates empty interface description with given name
2928    *
2929    * @param interfaceName name of the interface
2930    */
2931   DBusInterfaceDescription( std::string interfaceName );
2932
2933   /**
2934    * @brief adds new, synchronous method to the interface
2935    *
2936    * When method memberName is called on DBUS, callback functor will be called
2937    * with values received from DBUS. callback won't be called, if method was
2938    * called with invalid signature. Value returned from functor (or error message)
2939    * will be marshalled back to the caller.
2940    *
2941    * Template type T defines both arguments sent to the method
2942    * and expected values. Receiving different values will be reported as
2943    * error. For example:
2944    * \code{.cpp} Method<int(float, float)> \endcode
2945    * defines method, which takes two arguments (two floats) and return
2946    * single value of type int.
2947    *
2948    * @param memberName name of the method
2949    * @param callback functor, which will be called
2950    */
2951   template < typename T >
2952   void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
2953   {
2954     detail::CallId callId;
2955     MethodInfo mi;
2956     methods.push_back( std::move( mi ) );
2957     auto& z = methods.back();
2958     z.in = detail::EldbusArgGenerator_Args< T >::get( );
2959     z.out = detail::EldbusArgGenerator_ReturnType< T >::get( );
2960     z.memberName = memberName;
2961     DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2962                 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2963                 detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
2964     z.callback = construct< T >( callId, callback );
2965     z.id = callId;
2966   }
2967
2968   /**
2969    * @brief adds new, synchronous property to the interface
2970    *
2971    * When property memberName is called on DBUS, respective callback functor will be called
2972    * with values received from DBUS. callback won't be called, if method was
2973    * called with invalid signature. Value returned from functor (or error message)
2974    * will be marshalled back to the caller.
2975    *
2976    * Template type T defines type of the value hidden under property.
2977    * Note, that library automatically wraps both sent and received value into
2978    * DBUS's wrapper type.
2979    *
2980    * @param memberName name of the method
2981    * @param getter functor, which will be called when property is being read
2982    * @param setter functor, which will be called when property is being set
2983    */
2984   template < typename T >
2985   void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
2986   {
2987     properties.push_back( {} );
2988     auto& z = properties.back();
2989     z.memberName = memberName;
2990     z.typeSignature = detail::signature< T >::sig();
2991     if( getter )
2992     {
2993       detail::CallId getterId;
2994       z.getterId = getterId;
2995       DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
2996       z.getCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) -> std::string {
2997         try
2998         {
2999           auto v = detail::apply( getter, std::tuple<>{} );
3000           if( v )
3001           {
3002             detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
3003             DBUS_DEBUG( "call %d: success", getterId.id );
3004             return "";
3005           }
3006           DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
3007           return v.getError().message;
3008         }
3009         catch( std::exception& e )
3010         {
3011           return std::string( "unhandled exception (" ) + e.what() + ")";
3012         }
3013         catch( ... )
3014         {
3015           return "unhandled exception";
3016         }
3017       };
3018     }
3019     if( setter )
3020     {
3021       detail::CallId setterId;
3022       z.setterId = setterId;
3023       DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
3024       z.setCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &src_iter ) -> std::string {
3025         std::tuple< T > value;
3026         auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl( src_iter );
3027         if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
3028         {
3029           try
3030           {
3031             auto v = detail::apply( setter, std::move( value ) );
3032             if( v )
3033             {
3034               DBUS_DEBUG( "call %d: success", setterId.id );
3035               return "";
3036             }
3037             DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
3038             return v.getError().message;
3039           }
3040           catch( std::exception& e )
3041           {
3042             return std::string( "unhandled exception (" ) + e.what() + ")";
3043           }
3044           catch( ... )
3045           {
3046             return "unhandled exception";
3047           }
3048         }
3049         DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
3050                     src_signature.c_str(), detail::signature< T >::sig().c_str() );
3051         return "call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
3052                      src_signature + "', expected '" + detail::signature< T >::sig() + "'";
3053       };
3054     }
3055   }
3056
3057   /**
3058    * @brief adds new signal to the interface
3059    *
3060    * Template types ARGS defines values, which will be emited with the signal
3061    *
3062    * @param memberName name of the method
3063    */
3064   template < typename... ARGS >
3065   SignalId addSignal( const std::string& memberName )
3066   {
3067     detail::CallId callId;
3068     signals.push_back( {} );
3069     auto& z = signals.back();
3070     z.memberName = memberName;
3071     z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( DBUS_W->Strings );
3072     z.id = callId;
3073     DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
3074     return SignalId{callId};
3075   }
3076
3077 private:
3078   /// \cond
3079   std::vector< MethodInfo > methods;
3080   std::vector< PropertyInfo > properties;
3081   std::vector< SignalInfo > signals;
3082   std::string interfaceName;
3083
3084   template < typename T >
3085   std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > construct( detail::CallId callId,
3086                                                                            typename detail::dbus_interface_traits< T >::SyncCB callback )
3087   {
3088     using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
3089     return [=]( const DBusWrapper::MessagePtr &msg ) -> DBusWrapper::MessagePtr {
3090       DBUS_DEBUG( "call %d: entering", callId.id );
3091       DBusWrapper::MessagePtr ret = {};
3092       auto args = detail::unpackValues< VEArgs >( callId, msg );
3093       if( args )
3094       {
3095         try
3096         {
3097           auto v = detail::apply( callback, std::move( args.getValues() ) );
3098           if( v )
3099           {
3100             DBUS_DEBUG( "call %d: success", callId.id );
3101             ret = DBUS_W->eldbus_message_method_return_new_impl( msg );
3102             detail::packValues( callId, ret, v );
3103           }
3104           else
3105           {
3106             DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
3107             ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message );
3108           }
3109         }
3110         catch( std::exception& e )
3111         {
3112           auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
3113           DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
3114           ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", txt );
3115         }
3116         catch( ... )
3117         {
3118           DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
3119           ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
3120         }
3121       }
3122       else
3123       {
3124         std::ostringstream err;
3125         err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl( msg ) << "'";
3126         auto str = err.str();
3127         DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
3128         ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.InvalidArgs", str );
3129       }
3130       return ret;
3131     };
3132   }
3133   /// \endcond
3134 };
3135
3136 /**
3137  * @brief Class representing server's end of DBUS connection
3138  *
3139  * Allows listening (synchronously and asynchronosly) on methods on selected interface
3140  * Allows listening (synchronously and asynchronosly) on setting / getting properties.
3141  * Allows emiting signals.
3142  */
3143 class DBusServer
3144 {
3145 public:
3146   /**
3147    * @brief Constructs non-connected dbus server.
3148    */
3149   DBusServer() = default;
3150
3151   /**
3152    * @brief Constructs dbus server on either system or user dbus connection.
3153    */
3154   DBusServer( ConnectionType tp );
3155
3156   /**
3157    * @brief Constructs dbus server on connection from getDBusConnectionByType
3158    */
3159   DBusServer( const DBusWrapper::ConnectionPtr &conn );
3160
3161   /**
3162    * @brief Destructor
3163    *
3164    * Destructor will properly destroy everything. Destructor will cancel
3165    * pending replies.
3166    */
3167   ~DBusServer() = default;
3168
3169   DBusServer( const DBusServer& ) = delete;
3170   DBusServer( DBusServer&& ) = default;
3171
3172   DBusServer& operator=( DBusServer&& ) = default;
3173   DBusServer& operator=( const DBusServer& ) = delete;
3174
3175   /**
3176    * @brief Registers interface on given path name
3177    *
3178    * @param pathName path object to register interface on.
3179    * @param dscr
3180    * @param fallback
3181    */
3182   void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
3183
3184   /**
3185    * @brief Gets bus name of the current connection (must be connected)
3186    */
3187   std::string getBusName() const;
3188
3189   /**
3190    * @brief Returns connection object for this dbus server object
3191    *
3192    * @return connection object
3193    */
3194   DBusWrapper::ConnectionPtr getConnection();
3195
3196   /**
3197    * @brief Emits signal
3198    *
3199    * Emits signal based only on data passed to the function
3200    *
3201    * @param signal identifier of the signal
3202    * @param args values to emit
3203    */
3204   template < typename... ARGS >
3205   void emit2( const std::string& path, const std::string& interfaceName,
3206               const std::string& signalName, const ARGS&... args )
3207   {
3208     auto msg = DBUS_W->eldbus_message_signal_new_impl( path, interfaceName, signalName );
3209     detail::CallId id;
3210     detail::packValues( id, msg, args... );
3211     DBUS_W->eldbus_connection_send_impl( connection, msg );
3212   }
3213
3214   /**
3215    * @brief Returns current object path, when handling call to property / method
3216    *
3217    * User can call this function from inside callback used to handle property / method calls.
3218    * It will retrieve object's path used in the call. Note, that in asynchronous handling
3219    * of those calls user need to retrieve and store the current object / current connection
3220    * as the value will change at the moment user's callback handling will exit. For example:
3221    * \code{.cpp}
3222    * DBusInterfaceDescription interface{"name"};
3223    * auto handler_later = [](std::function<void(void)> done_cb) {
3224    *   // process something later on
3225    *   DBusServer::getCurrentObjectPath(); // this will return empty string
3226    * };
3227    * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3228    *   DBusServer::getCurrentObjectPath(); // this will current object's path
3229    *
3230    *   // do some processing later on and call done_cb, when it's done
3231    *   register_to_call_sometime_later_on(std::move(done_cb));
3232    * };
3233    * \endcode
3234    */
3235   static std::string getCurrentObjectPath() { return currentObjectPath; }
3236
3237   /**
3238    * @brief Returns current connection object, when handling call to property / method
3239    *
3240    * User can call this function from inside callback used to handle property / method calls.
3241    * It will retrieve object's path used in the call. Note, that in asynchronous handling
3242    * of those calls user need to retrieve and store the current object / current connection
3243    * as the value will change at the moment user's callback handling will exit. For example:
3244    * \code{.cpp}
3245    * DBusInterfaceDescription interface{"name"};
3246    * auto handler_later = [](std::function<void(void)> done_cb) {
3247    *   // process something later on
3248    *   DBusServer::getCurrentObjectPath(); // this will return empty string
3249    * };
3250    * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3251    *   DBusServer::getCurrentObjectPath(); // this will current object's path
3252    *
3253    *   // do some processing later on and call done_cb, when it's done
3254    *   register_to_call_sometime_later_on(std::move(done_cb));
3255    * };
3256    * \endcode
3257    */
3258   static const DBusWrapper::ConnectionPtr &getCurrentConnection() { return currentConnection; }
3259
3260   /// \cond
3261   class CurrentObjectSetter
3262   {
3263   public:
3264     CurrentObjectSetter( DBusWrapper::ConnectionPtr con, std::string path )
3265     {
3266       currentObjectPath = std::move(path);
3267       currentConnection = std::move( con );
3268     }
3269     ~CurrentObjectSetter()
3270     {
3271       currentObjectPath = "";
3272       currentConnection = {};
3273     }
3274     CurrentObjectSetter( const CurrentObjectSetter& ) = delete;
3275     CurrentObjectSetter( CurrentObjectSetter&& ) = delete;
3276     void operator=( const CurrentObjectSetter& ) = delete;
3277     void operator=( CurrentObjectSetter&& ) = delete;
3278   };
3279   /// \endcond
3280
3281 private:
3282   /// \cond
3283   DBusWrapper::ConnectionPtr connection;
3284   struct DestructorObject {
3285     std::vector<std::function<void()>> destructors;
3286     ~DestructorObject() {
3287       for(auto &a : destructors) a();
3288     }
3289   };
3290
3291   std::unique_ptr<DestructorObject> destructorObject { new DestructorObject() };
3292   static thread_local std::string currentObjectPath;
3293   static thread_local DBusWrapper::ConnectionPtr currentConnection;
3294
3295   /// \endcond
3296 };
3297
3298 /// \cond
3299 DBusWrapper::ConnectionPtr getDBusConnectionByType( ConnectionType tp );
3300 DBusWrapper::ConnectionPtr getDBusConnectionByName( const std::string& name );
3301 std::string getConnectionName( const DBusWrapper::ConnectionPtr& );
3302 /// \endcond
3303 }
3304
3305 /// \cond
3306 namespace std
3307 {
3308 template < size_t INDEX, typename... ARGS >
3309 inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
3310 {
3311   return std::get< INDEX >( v.getValues() );
3312 }
3313
3314 template < size_t INDEX, typename... ARGS >
3315 inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
3316 {
3317   return std::get< INDEX >( v.getValues() );
3318 }
3319 }
3320 /// \endcond
3321
3322 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H