1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
5 * Copyright 2019 Samsung Electronics Co., Ltd
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
32 #include <type_traits>
33 #include <unordered_map>
38 //#include <dali/public-api/adaptor-framework/accessibility.h>
39 //#include <dali/internal/accessibility/bridge/optional.h>
41 #include <dali/devel-api/adaptor-framework/accessibility.h>
43 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
44 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
48 #define bart_assert(x) do{}while(0)
60 virtual ~DBusWrapper() = default;
62 enum class ConnectionType
68 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
69 struct name { virtual ~name() = default; }; \
70 using name ## Ptr = std::shared_ptr<name>; \
71 using name ## WeakPtr = std::weak_ptr<name>; \
73 DEFINE_TYPE(Connection, Eldbus_Connection, )
74 DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close( Value ))
75 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
76 DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref( Value ))
77 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
78 DEFINE_TYPE(Pending, Eldbus_Pending, )
79 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
82 virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) = 0;
84 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
85 virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
86 virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
87 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
88 eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
90 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
91 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
92 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
93 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
94 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
95 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
96 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
97 eldbus_message_iter_arguments_append_impl_basic(double, d)
98 eldbus_message_iter_arguments_append_impl_basic(bool, b)
99 eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
100 eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
102 #undef eldbus_message_iter_arguments_append_impl_basic
103 #undef eldbus_message_iter_arguments_append_impl_basic_impl
105 virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) = 0;
106 virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) = 0;
107 virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) = 0;
108 virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) = 0;
109 virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) = 0;
110 virtual bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) = 0;
111 virtual std::string eldbus_message_signature_get_impl(const MessagePtr &msg) = 0;
113 using SendCallback = std::function<void(const MessagePtr &msg)>;
114 virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) = 0;
115 virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) = 0;
116 virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) = 0;
117 virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) = 0;
118 virtual MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) = 0;
119 virtual MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) = 0;
120 virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) = 0;
121 virtual MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) = 0;
122 virtual MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) = 0;
123 virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
124 virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) = 0;
125 virtual ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) = 0;
126 virtual ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) = 0;
127 virtual ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) = 0;
132 struct char_ptr_deleter
134 void operator()( char* p )
139 std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
141 const char* add( const char* txt )
143 auto ptr = strdup( txt );
144 storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
145 return storage.back().get();
147 const char* add( const std::string& txt )
149 return add( txt.c_str() );
155 static std::atomic< unsigned int > LastId;
156 unsigned int id = ++LastId;
161 std::string memberName;
162 std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
163 std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > callback;
168 std::string memberName;
169 std::vector< std::pair<std::string, std::string> > args;
170 unsigned int uniqueId;
174 CallId setterId, getterId;
175 std::string memberName, typeSignature;
176 std::function< std::string( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) > getCallback, setCallback;
182 SignalId() = default;
183 SignalId( CallId id ) : id( id ) {}
185 virtual void add_interface_impl( bool fallback, const std::string& pathName,
186 const ConnectionPtr &connection,
187 std::vector<std::function<void()>> &destructors,
188 const std::string& interfaceName,
189 std::vector< MethodInfo >& dscrMethods,
190 std::vector< PropertyInfo >& dscrProperties,
191 std::vector< SignalInfo >& dscrSignals ) = 0;
192 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;
193 static DBusWrapper *Installed();
194 static void Install(std::unique_ptr<DBusWrapper>);
196 StringStorage Strings;
200 enum class MethodType {
201 Method, Getter, Setter
206 template <> struct hash<std::tuple<std::string, std::string, std::string>> {
207 size_t operator () (const std::tuple<std::string, std::string, std::string> &a) const {
208 auto a1 = std::hash<std::string>()(std::get<0>(a));
209 auto a2 = std::hash<std::string>()(std::get<1>(a));
210 auto a3 = std::hash<std::string>()(std::get<2>(a));
212 v = (v * 11400714819323198485llu) + a2;
213 v = (v * 11400714819323198485llu) + a3;
217 template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
218 size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType> &a) const {
219 auto a1 = std::hash<std::string>()(std::get<0>(a));
220 auto a2 = std::hash<std::string>()(std::get<1>(a));
221 auto a3 = std::hash<std::string>()(std::get<2>(a));
222 auto a4 = static_cast<size_t>(std::get<3>(a));
224 v = (v * 11400714819323198485llu) + a2;
225 v = (v * 11400714819323198485llu) + a3;
226 v = (v * 11400714819323198485llu) + a4;
230 template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
231 size_t operator () (const std::tuple<std::string, std::string, unsigned int> &a) const {
232 auto a1 = std::hash<std::string>()(std::get<0>(a));
233 auto a2 = std::hash<std::string>()(std::get<1>(a));
234 auto a3 = std::get<2>(a);
236 v = (v * 11400714819323198485llu) + a2;
237 v = (v * 11400714819323198485llu) + a3;
243 template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
244 template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
245 template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
246 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 };
248 template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
249 template <typename T, typename Q> struct IndexFromTypeTuple {
250 enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
252 template <typename T, typename = void> struct Encoder;
253 template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
255 struct TestDBusWrapper : public DBusWrapper
257 using MethodType = detail::MethodType;
258 ConnectionPtr connection;
259 std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> testMethods;
260 std::unordered_map<std::tuple<std::string, std::string, std::string, MethodType>, std::function<MessagePtr(const MessagePtr&)>> daliMethods;
261 std::unordered_map<std::tuple<std::string, std::string, unsigned int>, std::string> daliSignalsMap;
262 std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const MessagePtr&)>> daliSignals;
263 std::unordered_map<std::tuple<std::string, std::string, std::string>, std::function<void(const _Eina_Value *)>> propertyChangeListeners;
265 std::vector<std::function<void()>> asyncCalls;
267 template <typename T> struct Variant {
270 Variant(T t) : value(std::move(t)) { }
272 template <typename ... ARGS> void Encode(const MessagePtr &m, const std::tuple<ARGS...> &args) {
273 auto iter = eldbus_message_iter_get_impl(m, true);
274 detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(*this, iter, args);
276 template <typename ... ARGS> void Decode(const MessagePtr &m, std::tuple<ARGS...> &args) {
277 auto iter = eldbus_message_iter_get_impl(m, false);
278 detail::EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(*this, args, iter);
280 MessagePtr newMessage(const std::string &path, const std::string &interface, const std::string &name, bool reply);
281 MessagePtr newReplyMessage(const MessagePtr &m);
283 template <typename ... ARGS> void fromTestEmitSignal(std::string path, const std::string &interface, const std::string &name, const std::tuple<ARGS...> &args) {
284 if (path.empty()) throw error{};
285 if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
286 auto msg = newMessage(path, interface, name, false);
288 auto it = daliSignals.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
289 if (it == daliSignals.end()) throw error{};
292 static std::shared_ptr<_Eina_Value> createEinaValue(bool);
293 template <typename T> void fromTestChangeProperty(std::string path, const std::string &interface, const std::string &name, T new_value) {
294 auto v = createEinaValue(new_value);
295 if (path.empty()) throw error{};
296 if (path[0] != '/') path = "/org/a11y/atspi/accessible/" + path;
297 auto it = propertyChangeListeners.find(std::tuple<std::string, std::string, std::string>{ path, interface, name });
298 if (it == propertyChangeListeners.end()) throw error{};
301 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) {
302 auto msg = newMessage(path, interface, name, false);
304 auto res = call(daliMethods, "daliMethods", msg, MethodType::Method);
306 if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
307 std::tuple<ARGS1...> tmp;
311 template <typename T> T fromTestGet(const std::string &path, const std::string &interface, const std::string &name) {
312 auto msg = newMessage(path, interface, name, false);
313 auto res = call(daliMethods, "daliMethods", msg, MethodType::Getter);
315 if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
318 return std::move(std::get<0>(tmp));
320 template <typename ... ARGS1, typename T> std::tuple<ARGS1...> fromTestSet(const std::string &path, const std::string &interface, const std::string &name, const T &arg) {
321 auto msg = newMessage(path, interface, name, false);
322 Encode(msg, TestDBusWrapper::Variant<T>{ arg });
323 auto res = call(daliMethods, "daliMethods", msg, MethodType::Setter);
325 if (eldbus_message_error_get_impl(res, a, b)) throw error{} << "call to " << path << " " << interface << " " << name << " failed: " << a << ": " << b;
326 std::tuple<ARGS1...> tmp;
334 class error : public std::exception {
335 std::shared_ptr<std::ostringstream> temp = std::make_shared<std::ostringstream>();
336 mutable std::string text;
340 template <typename T> error &operator << (T &&t) {
341 *temp << std::forward<T>(t);
344 const char *what() const noexcept override {
349 #define DEFINE_TYPE(name) struct name ## Impl; static name ## Impl *get(const name ## Ptr &);
350 DEFINE_TYPE(Connection)
354 DEFINE_TYPE(MessageIter)
358 using ElementList = std::list<Element>;
359 using ElementMap = std::map<std::string, std::string>;
360 using ElementTuple = std::tuple<
361 uint8_t, uint16_t, uint32_t, uint64_t, int16_t, int32_t, int64_t, double, bool, std::string, ObjectPath,
367 char signature_ = 0, end_ = 0, index_ = 0;
368 template <typename T> void set(T &&t, char signature = detail::DBusSig<T>::value) {
369 signature_ = signature;
370 end_ = detail::DBusSig<T>::end;
371 index_ = static_cast<char>(detail::IndexFromTypeTuple<ElementTuple, T>::value);
372 get<T>() = std::forward<T>(t);
375 template <typename T> Element(T &&t, typename std::enable_if<detail::DBusSig<T>::value != 0>::type* = nullptr) { set(std::forward<T>(t)); }
376 Element(ElementList t, int signature) { set(std::move(t), static_cast<char>(signature)); }
378 char signature() const { return signature_; }
379 char end() const { return end_; }
380 char index() const { return index_; }
381 bool isContainer() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, ElementList>::value; }
382 template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
383 bool is() const { return index_ == detail::IndexFromTypeTuple<ElementTuple, T>::value; }
384 template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
385 const T &get() const { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
386 template <typename T, typename = typename std::enable_if<detail::DBusSig<T>::value != 0>::type>
387 T &get() { if (!is<T>()) throw error{}; return std::get<detail::IndexFromTypeTuple<ElementTuple, T>::value>(data); }
390 ConnectionPtr eldbus_address_connection_get_impl(const std::string &addr) override;
392 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
393 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) override; \
394 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) override;
395 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
396 eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
398 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
399 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
400 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
401 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
402 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
403 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
404 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
405 eldbus_message_iter_arguments_append_impl_basic(double, d)
406 eldbus_message_iter_arguments_append_impl_basic(bool, b)
407 eldbus_message_iter_arguments_append_impl_basic_impl(const std::string &, std::string, s)
408 eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath &, ObjectPath, o)
410 #undef eldbus_message_iter_arguments_append_impl_basic
411 #undef eldbus_message_iter_arguments_append_impl_basic_impl
413 MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override;
414 MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override;
415 MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &it, bool write) override;
416 MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName) override;
417 MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override;
418 bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override;
419 std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override;
420 PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override;
421 std::string eldbus_proxy_interface_get_impl(const ProxyPtr &) override;
422 void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override;
423 std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override;
424 MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override;
425 MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override;
426 PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override;
427 MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override;
428 MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override;
429 ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override;
430 std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override;
431 ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override;
432 ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override;
433 ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override;
434 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;
435 void add_interface_impl( bool fallback, const std::string& pathName,
436 const ConnectionPtr &connection,
437 std::vector<std::function<void()>> &destructors,
438 const std::string& interfaceName,
439 std::vector< MethodInfo >& dscrMethods,
440 std::vector< PropertyInfo >& dscrProperties,
441 std::vector< SignalInfo >& dscrSignals ) override;
442 static bool completed(const MessageIterPtr &iter);
444 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);
448 template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
449 template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
450 template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
451 template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
452 template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
453 template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
454 template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
455 template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
456 template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
457 template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
458 template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
459 template <> struct DBusSigImpl<TestDBusWrapper::ElementList> { enum { value = '(', end = ')' }; };
460 template <> struct DBusSigImpl<TestDBusWrapper::ElementMap> { enum { value = '{', end = '}' }; };
462 template <typename T> struct Encoder<T, decltype(TestDBusWrapper().eldbus_message_iter_arguments_append_impl(TestDBusWrapper::MessageIterPtr(), T()))> {
463 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
464 w.eldbus_message_iter_arguments_append_impl(tgt, src);
466 static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
467 if (!w.eldbus_message_iter_get_and_next_impl(src, tgt)) throw TestDBusWrapper::error{};
470 template <typename T> struct Encoder<T, typename std::enable_if<std::is_enum<T>::value>::type> {
471 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
472 Encoder<typename std::underlying_type<T>::type>::encode(w, tgt, static_cast<typename std::underlying_type<T>::type>(src));
474 static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
475 typename std::underlying_type<T>::type v = 0;
476 Encoder<typename std::underlying_type<T>::type>::decode(w, v, src);
477 tgt = static_cast<T>(v);
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);
484 static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
485 Encoder<T>::decode(w, tgt, src);
488 template <typename T> struct Encoder<const T &> {
489 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
490 Encoder<T>::encode(w, tgt, src);
492 static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
493 Encoder<T>::decode(w, tgt, src);
496 template <typename T> struct Encoder<T &> {
497 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const T &src) {
498 Encoder<T>::encode(w, tgt, src);
500 static void decode(TestDBusWrapper &w, T &tgt, const TestDBusWrapper::MessageIterPtr &src) {
501 Encoder<T>::decode(w, tgt, src);
504 template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple {
505 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
506 Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::encode(w, tgt, std::get<I>(src));
507 EncoderTuple<I + 1, S, ARGS...>::encode(w, tgt, src);
509 static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
510 Encoder<typename std::tuple_element<I, std::tuple<ARGS...>>::type>::decode(w, std::get<I>(tgt), src);
511 EncoderTuple<I + 1, S, ARGS...>::decode(w, tgt, src);
514 template <size_t S, typename ... ARGS> struct EncoderTuple<S, S, ARGS...> {
515 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) { }
516 static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) { }
518 template <typename ...ARGS> struct Encoder<std::tuple<ARGS...>> {
519 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::tuple<ARGS...> &src) {
520 auto var = w.eldbus_message_iter_container_new_impl( tgt, 'r', "");
521 EncoderTuple<0, sizeof...(ARGS), ARGS...>::encode(w, var, src);
523 static void decode(TestDBusWrapper &w, std::tuple<ARGS...> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
524 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'r' );
525 if( !s ) throw TestDBusWrapper::error{};
526 EncoderTuple<0, sizeof...(ARGS), ARGS...>::decode(w, tgt, s);
529 template <typename A, typename B> struct Encoder<std::pair<A, B>> {
530 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::pair<A, B> &src, char type = 'r') {
531 auto var = w.eldbus_message_iter_container_new_impl( tgt, type, "");
532 Encoder<A>::encode(w, var, src.first);
533 Encoder<B>::encode(w, var, src.second);
535 static void decode(TestDBusWrapper &w, std::pair<A, B> &tgt, const TestDBusWrapper::MessageIterPtr &src, char type = 'r') {
536 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, type );
537 if( !s ) throw TestDBusWrapper::error{};
538 Encoder<A>::decode(w, tgt.first, s);
539 Encoder<B>::decode(w, tgt.second, s);
542 template <typename T> struct Encoder<TestDBusWrapper::Variant<T>> {
543 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const TestDBusWrapper::Variant<T> &src) {
544 //w.eldbus_message_iter_arguments_append_impl(tgt, src);
545 auto var = w.eldbus_message_iter_container_new_impl( tgt, 'v', "");
546 Encoder<T>::encode(w, var, src.value);
548 static void decode(TestDBusWrapper &w, TestDBusWrapper::Variant<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
549 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'v' );
550 if( !s ) throw TestDBusWrapper::error{};
551 Encoder<T>::decode(w, tgt.value, s);
554 template <typename T> struct Encoder<std::vector<T>> {
555 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::vector<T> &src) {
556 auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
558 Encoder<T>::encode(w, var, q);
560 static void decode(TestDBusWrapper &w, std::vector<T> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
561 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
562 if( !s ) throw TestDBusWrapper::error{};
563 while(!TestDBusWrapper::completed(s)) {
565 Encoder<T>::decode(w, tgt.back(), s);
569 template <typename K, typename V> struct Encoder<std::unordered_map<K,V>> {
570 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::unordered_map<K,V> &src) {
571 auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
573 Encoder<typename std::unordered_map<K,V>::value_type>::encode(w, var, q, 'e');
576 static void decode(TestDBusWrapper &w, std::unordered_map<K,V> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
577 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
578 if( !s ) throw TestDBusWrapper::error{};
579 while(!TestDBusWrapper::completed(s)) {
581 Encoder<std::pair<K,V>>::decode(w, tmp, s, 'e');
582 tgt.insert(std::move(tmp));
586 template <typename T, size_t I> struct Encoder<std::array<T, I>> {
587 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const std::array<T, I> &src) {
588 auto var = w.eldbus_message_iter_container_new_impl( tgt, 'a', "");
590 Encoder<T>::encode(w, var, q);
592 static void decode(TestDBusWrapper &w, std::array<T, I> &tgt, const TestDBusWrapper::MessageIterPtr &src) {
593 auto s = w.eldbus_message_iter_get_and_next_by_type_impl( src, 'a' );
594 if( !s ) throw TestDBusWrapper::error{};
596 while(!TestDBusWrapper::completed(s)) {
597 if(i >= tgt.size()) throw TestDBusWrapper::error{};
598 Encoder<T>::decode(w, tgt[i], s);
601 if( i!=tgt.size()) throw TestDBusWrapper::error{};
604 template <> struct Encoder<Dali::Accessibility::Address> {
605 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const Dali::Accessibility::Address &src) {
606 Encoder<std::tuple<std::string, ObjectPath>>::encode(w, tgt,std::tuple<std::string, ObjectPath> {
607 src.GetBus(), ObjectPath{ "/org/a11y/atspi/accessible/" + src.GetPath() } }
610 static void decode(TestDBusWrapper &w, Dali::Accessibility::Address &tgt, const TestDBusWrapper::MessageIterPtr &src) {
611 std::tuple<std::string, ObjectPath> tmp;
612 Encoder<std::tuple<std::string, ObjectPath>>::decode(w, tmp, src);
613 static const size_t prefixSize = std::string{ "/org/a11y/atspi/accessible/" }.size();
614 tgt = { std::move(std::get<0>(tmp)), std::get<1>(tmp).value.substr(prefixSize) };
617 template <> struct Encoder<const char*> {
618 static void encode(TestDBusWrapper &w, const TestDBusWrapper::MessageIterPtr &tgt, const char *src) {
619 Encoder<std::string>::encode(w, tgt, src);
625 #define DBUS_DEBUG( ... ) \
628 DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
631 #define DBUS_W DBusWrapper::Installed()
634 * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
636 * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
637 * when using eldbus from C++.
640 * - takes care of marshalling arguments to and from DBUS calls.
641 * - allows synchronous and asynchronous calls.
642 * - allows synchronous and asynchronous listeners on signals.
643 * - manages all involved objects' lifetimes.
644 * - errors are passed as optional-alike objects, no exceptions are used.
645 * - allows setting additional debug-print function for more details about
648 * DBUS's method signatures (and expected return values) are specified as template argument,
649 * using functor syntax. For example:
651 * auto dbus = DBusClient{ ... };
652 * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
654 * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
655 * of types float, float and string (float will be automatically converted to double).
656 * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
657 * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
658 * Slightly different (asynchronous) example:
660 * auto dbus = DBusClient{ ... };
661 * std::function<void(ValueOrError<int, float>)> callback;
662 * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
664 * Now the call takes the same arguments and has the same signature. But expected values are different -
665 * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
666 * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
667 * you need to pass a callback, which will be called either with received data and error message.
669 * Library is not thread-safe, the same object shouldn't be called from different threads without
670 * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
677 class DBusInterfaceDescription;
680 * @brief Formats debug message and calls debug printer (if any) with it
682 void debugPrint( const char* file, size_t line, const char* format, ... );
685 * @brief Sets debug printer callback, which will be called with debug messages
687 * Callback will be called in various moments of DBus activity. First value passed to callback
688 * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
689 * user can safely printf it.
691 void setDebugPrinter( std::function< void( const char*, size_t ) > );
698 Error( std::string msg ) : message( std::move( msg ) )
700 bart_assert( !message.empty() );
710 * @brief Value representing data, that came from DBUS or error message
712 * Object of this class either helds series of values (of types ARGS...)
713 * or error message. This object will be true in boolean context, if has data
714 * and false, if an error occured.
715 * It's valid to create ValueOrError object with empty argument list or void:
718 * ValueOrError<void> v2;
720 * Both mean the same - ValueOrError containing no real data and being a marker,
721 * wherever operation successed or failed and containing possible error message.
723 template < typename... ARGS >
728 * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
730 ValueOrError() = default;
733 * @brief Value constructor.
735 * This will be initialized as success with passed in values.
737 ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
740 * @brief Alternative Value constructor.
742 * This will be initialized as success with passed in values.
744 ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
747 * @brief Error constructor. This will be initialized as failure with given error message.
749 ValueOrError( Error e ) : error( std::move( e ) )
751 bart_assert( !error.message.empty() );
755 * @brief bool operator.
757 * Returns true, if operation was successful (getValues member is callable), or false
758 * when operation failed (getError is callable).
760 explicit operator bool() const
762 return error.message.empty();
766 * @brief Returns error message object.
768 * Returns object containing error message associated with the failed operation.
769 * Only callable, if operation actually failed, otherwise will bart_assert.
771 const Error& getError() const
777 * @brief Returns modifiable tuple of held data.
779 * Returns reference to the internal tuple containing held data.
780 * User can modify (or move) data safely.
781 * Only callable, if operation actually successed, otherwise will bart_assert.
783 std::tuple< ARGS... >& getValues()
785 bart_assert( *this );
790 * @brief Returns const tuple of held data.
792 * Returns const reference to the internal tuple containing held data.
793 * Only callable, if operation actually successed, otherwise will bart_assert.
795 const std::tuple< ARGS... >& getValues() const
797 bart_assert( *this );
803 std::tuple< ARGS... > value;
813 ValueOrError() = default;
814 ValueOrError( std::tuple<> t ) {}
815 ValueOrError( Error e ) : error( std::move( e ) )
817 bart_assert( !error.message.empty() );
820 explicit operator bool() const
822 return error.message.empty();
824 const Error& getError() const
828 std::tuple<>& getValues()
830 bart_assert( *this );
831 static std::tuple<> t;
834 std::tuple<> getValues() const
836 bart_assert( *this );
845 class ValueOrError< void >
848 ValueOrError() = default;
849 ValueOrError( Success ) {}
850 ValueOrError( Error e ) : error( std::move( e ) )
852 bart_assert( !error.message.empty() );
855 explicit operator bool() const
857 return error.message.empty();
859 const Error& getError() const
863 std::tuple<>& getValues()
865 bart_assert( *this );
866 static std::tuple<> t;
869 std::tuple<> getValues() const
871 bart_assert( *this );
879 using ObjectPath = ObjectPath;
884 * @brief Class used to marshall DBUS's variant type
886 * Minimalistic class, that allows user to specify DBUS variant type
887 * as argument or return value. You need to pass real type hidden under variant as
888 * template type \b A. At this point library doesn't allow to expected one of few classes
889 * as return data in variant. So for example user can't specify method call, which on return
890 * expects DBUS variant holding either string or int.
892 template < typename A >
899 * @brief Namespace for private, internal functions and classes
904 template < typename T, typename = void >
906 template < typename... ARGS >
907 struct signature< std::tuple< ARGS... > >;
908 template < typename A, typename B >
909 struct signature< std::pair< A, B > >;
910 template < typename A >
911 struct signature< std::vector< A > >;
912 template < typename A, size_t N >
913 struct signature< std::array< A, N > >;
914 template < typename A, typename B >
915 struct signature< std::unordered_map< A, B > >;
916 template < typename A, typename B >
917 struct signature< std::map< A, B > >;
921 * @brief Signature class for marshalling uint8 type.
924 struct signature< uint8_t >
927 * @brief Returns name of type marshalled, for informative purposes
929 static std::string name()
935 * @brief Returns DBUS' signature of type marshalled
937 static std::string sig()
943 * @brief Marshals value v as marshalled type into message
945 static void set( const DBusWrapper::MessageIterPtr &iter, uint8_t v )
947 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
951 * @brief Marshals value from marshalled type into variable v
953 static bool get( const DBusWrapper::MessageIterPtr &iter, uint8_t& v )
955 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
960 * @brief Signature class for marshalling uint16 type.
963 struct signature< uint16_t >
966 * @brief Returns name of type marshalled, for informative purposes
968 static std::string name()
974 * @brief Returns DBUS' signature of type marshalled
976 static std::string sig()
982 * @brief Marshals value v as marshalled type into message
984 static void set( const DBusWrapper::MessageIterPtr &iter, uint16_t v )
986 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
990 * @brief Marshals value from marshalled type into variable v
992 static bool get( const DBusWrapper::MessageIterPtr &iter, uint16_t& v )
994 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
999 * @brief Signature class for marshalling uint32 type.
1002 struct signature< uint32_t >
1005 * @brief Returns name of type marshalled, for informative purposes
1007 static std::string name()
1013 * @brief Returns DBUS' signature of type marshalled
1015 static std::string sig()
1021 * @brief Marshals value v as marshalled type into message
1023 static void set( const DBusWrapper::MessageIterPtr &iter, uint32_t v )
1025 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1029 * @brief Marshals value from marshalled type into variable v
1031 static bool get( const DBusWrapper::MessageIterPtr &iter, uint32_t& v )
1033 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1038 * @brief Signature class for marshalling uint64 type.
1041 struct signature< uint64_t >
1044 * @brief Returns name of type marshalled, for informative purposes
1046 static std::string name()
1052 * @brief Returns DBUS' signature of type marshalled
1054 static std::string sig()
1060 * @brief Marshals value v as marshalled type into message
1062 static void set( const DBusWrapper::MessageIterPtr &iter, uint64_t v )
1064 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1068 * @brief Marshals value from marshalled type into variable v
1070 static bool get( const DBusWrapper::MessageIterPtr &iter, uint64_t& v )
1072 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1077 * @brief Signature class for marshalling int16 type.
1080 struct signature< int16_t >
1083 * @brief Returns name of type marshalled, for informative purposes
1085 static std::string name()
1091 * @brief Returns DBUS' signature of type marshalled
1093 static std::string sig()
1099 * @brief Marshals value v as marshalled type into message
1101 static void set( const DBusWrapper::MessageIterPtr &iter, int16_t v )
1103 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1107 * @brief Marshals value from marshalled type into variable v
1109 static bool get( const DBusWrapper::MessageIterPtr &iter, int16_t& v )
1111 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1116 * @brief Signature class for marshalling int32 type.
1119 struct signature< int32_t >
1122 * @brief Returns name of type marshalled, for informative purposes
1124 static std::string name()
1130 * @brief Returns DBUS' signature of type marshalled
1132 static std::string sig()
1138 * @brief Marshals value v as marshalled type into message
1140 static void set( const DBusWrapper::MessageIterPtr &iter, int32_t v )
1142 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1146 * @brief Marshals value from marshalled type into variable v
1148 static bool get( const DBusWrapper::MessageIterPtr &iter, int32_t& v )
1150 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1155 * @brief Signature class for marshalling int64 type.
1158 struct signature< int64_t >
1161 * @brief Returns name of type marshalled, for informative purposes
1163 static std::string name()
1169 * @brief Returns DBUS' signature of type marshalled
1171 static std::string sig()
1177 * @brief Marshals value v as marshalled type into message
1179 static void set( const DBusWrapper::MessageIterPtr &iter, int64_t v )
1181 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1185 * @brief Marshals value from marshalled type into variable v
1187 static bool get( const DBusWrapper::MessageIterPtr &iter, int64_t& v )
1189 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1194 * @brief Signature class for marshalling double type.
1197 struct signature< double >
1200 * @brief Returns name of type marshalled, for informative purposes
1202 static std::string name()
1208 * @brief Returns DBUS' signature of type marshalled
1210 static std::string sig()
1216 * @brief Marshals value v as marshalled type into message
1218 static void set( const DBusWrapper::MessageIterPtr &iter, double v )
1220 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1224 * @brief Marshals value from marshalled type into variable v
1226 static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1228 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1232 * @brief Marshals value from marshalled type into variable v
1234 static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1237 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1238 v2 = static_cast< float >( v );
1244 * @brief Signature class for marshalling float type.
1247 struct signature< float >
1250 * @brief Returns name of type marshalled, for informative purposes
1252 static std::string name()
1258 * @brief Returns DBUS' signature of type marshalled
1260 static std::string sig()
1266 * @brief Marshals value v as marshalled type into message
1268 static void set( const DBusWrapper::MessageIterPtr &iter, float v )
1270 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1274 * @brief Marshals value from marshalled type into variable v
1276 static bool get( const DBusWrapper::MessageIterPtr &iter, double& v )
1278 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1282 * @brief Marshals value from marshalled type into variable v
1284 static bool get( const DBusWrapper::MessageIterPtr &iter, float& v2 )
1287 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1288 v2 = static_cast< float >( v );
1294 * @brief Signature class for marshalling boolean type.
1297 struct signature< bool >
1300 * @brief Returns name of type marshalled, for informative purposes
1302 static std::string name()
1308 * @brief Returns DBUS' signature of type marshalled
1310 static std::string sig()
1316 * @brief Marshals value v as marshalled type into message
1318 static void set( const DBusWrapper::MessageIterPtr &iter, bool v )
1320 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1324 * @brief Marshals value from marshalled type into variable v
1326 static bool get( const DBusWrapper::MessageIterPtr &iter, bool& v )
1328 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1332 template < typename T >
1333 struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
1336 * @brief Returns name of type marshalled, for informative purposes
1338 static std::string name()
1344 * @brief Returns DBUS' signature of type marshalled
1346 static std::string sig()
1348 return signature<typename std::underlying_type<T>::type>::sig();
1352 * @brief Marshals value v as marshalled type into message
1354 static void set( const DBusWrapper::MessageIterPtr &iter, T v )
1356 signature<typename std::underlying_type<T>::type>::set(iter, static_cast< int64_t >( v ));
1360 * @brief Marshals value from marshalled type into variable v
1362 static bool get( const DBusWrapper::MessageIterPtr &iter, T& v )
1364 typename std::underlying_type<T>::type q = 0;
1365 if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
1368 v = static_cast< T >( q );
1374 * @brief Signature class for marshalling string type.
1376 * Both (const) char * and std::string types are accepted as value to send.
1377 * Only std::string is accepted as value to receive.
1380 struct signature< std::string >
1383 * @brief Returns name of type marshalled, for informative purposes
1385 static std::string name()
1391 * @brief Returns DBUS' signature of type marshalled
1393 static std::string sig()
1399 * @brief Marshals value v as marshalled type into message
1401 static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1403 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1407 // * @brief Marshals value v as marshalled type into message
1409 // static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1411 // DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1415 * @brief Marshals value from marshalled type into variable v
1417 static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1419 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1424 struct signature< ObjectPath >
1427 * @brief Returns name of type marshalled, for informative purposes
1429 static std::string name()
1435 * @brief Returns DBUS' signature of type marshalled
1437 static std::string sig()
1443 * @brief Marshals value v as marshalled type into message
1445 static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1447 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1451 * @brief Marshals value v as marshalled type into message
1453 static void set( const DBusWrapper::MessageIterPtr &iter, const ObjectPath& v )
1455 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1459 * @brief Marshals value v as marshalled type into message
1461 static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1463 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1467 * @brief Marshals value from marshalled type into variable v
1469 static bool get( const DBusWrapper::MessageIterPtr &iter, ObjectPath& v )
1471 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1475 * @brief Marshals value from marshalled type into variable v
1477 static bool get( const DBusWrapper::MessageIterPtr &iter, std::string& v )
1480 if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1481 v = std::move(q.value);
1487 * @brief Signature class for marshalling (const) char * type.
1489 * Both (const) char * and std::string types are accepted as value to send.
1490 * You can't use (const) char * variable type to receive value.
1493 struct signature< char* >
1496 * @brief Returns name of type marshalled, for informative purposes
1498 static std::string name()
1504 * @brief Returns DBUS' signature of type marshalled
1506 static std::string sig()
1512 * @brief Marshals value v as marshalled type into message
1514 static void set( const DBusWrapper::MessageIterPtr &iter, const std::string& v )
1516 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1520 * @brief Marshals value v as marshalled type into message
1522 static void set( const DBusWrapper::MessageIterPtr &iter, const char* v )
1524 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1529 template < size_t INDEX, typename A, typename... ARGS >
1530 struct signature_tuple_element_type_helper
1532 using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1535 template < typename A, typename... ARGS >
1536 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1543 * @brief Helper class to marshall tuples
1545 * This class marshals all elements of the tuple value starting at the index INDEX
1546 * and incrementing. This class recursively calls itself with increasing INDEX value
1547 * until INDEX is equal to SIZE, where recursive calling ends.
1549 template < size_t INDEX, size_t SIZE, typename... ARGS >
1550 struct signature_tuple_helper
1552 using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1555 * @brief Returns name of type marshalled, for informative purposes
1557 static std::string name()
1559 if( INDEX + 1 >= SIZE )
1560 return signature< current_type >::name();
1561 return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
1565 * @brief Returns DBUS' signature of type marshalled
1567 static std::string sig()
1569 return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1573 * @brief Marshals value v as marshalled type into message
1575 static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1577 signature< current_type >::set( iter, std::get< INDEX >( args ) );
1578 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
1582 * @brief Marshals value from marshalled type into variable v
1584 static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1586 return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
1587 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
1592 * @brief Helper class to marshall tuples
1594 * This class marks end of the tuple marshalling. Members of this class are called
1595 * when INDEX value is equal to SIZE.
1597 template < size_t SIZE, typename... ARGS >
1598 struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1601 * @brief Returns name of type marshalled, for informative purposes
1603 static std::string name()
1609 * @brief Returns DBUS' signature of type marshalled
1611 static std::string sig()
1617 * @brief Marshals value v as marshalled type into message
1619 static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1624 * @brief Marshals value from marshalled type into variable v
1626 static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1633 * @brief Signature class for marshalling tuple of values
1635 * This class marshalls tuple of values. This represents
1636 * DBUS struct typle, encoded with character 'r'
1638 template < typename... ARGS >
1639 struct signature< std::tuple< ARGS... > >
1642 * @brief Returns name of type marshalled, for informative purposes
1644 static std::string name()
1646 return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1650 * @brief Returns DBUS' signature of type marshalled
1652 static std::string sig()
1654 return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
1658 * @brief Marshals value v as marshalled type into message
1660 static void set( const DBusWrapper::MessageIterPtr &iter, const std::tuple< ARGS... >& args )
1662 auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'r', "");
1663 signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
1667 * @brief Marshals value from marshalled type into variable v
1669 static bool get( const DBusWrapper::MessageIterPtr &iter, std::tuple< ARGS... >& args )
1671 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1672 if (!entry) return false;
1673 return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
1678 * @brief Signature class for marshalling ValueOrError template type
1680 * ValueOrError template type is used to marshall list of values passed to
1681 * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1682 * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1683 * While (ss(s)) is represented as
1684 * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1686 * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1688 template < typename... ARGS >
1689 struct signature< ValueOrError< ARGS... > >
1692 * @brief Returns name of type marshalled, for informative purposes
1694 static std::string name()
1696 return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1700 * @brief Returns DBUS' signature of type marshalled
1702 static std::string sig()
1704 return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
1708 * @brief Marshals value v as marshalled type into message
1710 static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< ARGS... >& args )
1712 signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
1716 * @brief Marshals value from marshalled type into variable v
1718 static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< ARGS... >& args )
1720 return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
1725 * @brief Signature class for marshalling ValueOrError<void> type
1728 struct signature< ValueOrError< void > >
1731 * @brief Returns name of type marshalled, for informative purposes
1733 static std::string name()
1735 return "ValueOrError<void>";
1739 * @brief Returns DBUS' signature of type marshalled
1741 static std::string sig()
1747 * @brief Marshals value v as marshalled type into message
1749 static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError< void >& args )
1754 * @brief Marshals value from marshalled type into variable v
1756 static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError< void >& args )
1763 * @brief Signature class for marshalling ValueOrError<> type
1766 struct signature< ValueOrError<> >
1769 * @brief Returns name of type marshalled, for informative purposes
1771 static std::string name()
1773 return "ValueOrError<>";
1777 * @brief Returns DBUS' signature of type marshalled
1779 static std::string sig()
1785 * @brief Marshals value v as marshalled type into message
1787 static void set( const DBusWrapper::MessageIterPtr &iter, const ValueOrError<>& args )
1792 * @brief Marshals value from marshalled type into variable v
1794 static bool get( const DBusWrapper::MessageIterPtr &iter, ValueOrError<>& args )
1801 * @brief Signature class for marshalling pair of types
1803 template < typename A, typename B >
1804 struct signature< std::pair< A, B > >
1807 * @brief Returns name of type marshalled, for informative purposes
1809 static std::string name()
1811 return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1815 * @brief Returns DBUS' signature of type marshalled
1817 static std::string sig()
1819 return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1823 * @brief Marshals value v as marshalled type into message
1825 static void set( const DBusWrapper::MessageIterPtr &iter, const std::pair< A, B >& ab, bool dictionary = false )
1827 auto entry = DBUS_W->eldbus_message_iter_container_new_impl( iter, dictionary ? 'e' : 'r', "");
1828 signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
1832 * @brief Marshals value from marshalled type into variable v
1834 static bool get( const DBusWrapper::MessageIterPtr &iter, std::pair< A, B >& ab )
1836 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'r' );
1838 entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, '{' );
1839 if (!entry) return false;
1842 std::tuple< A, B > ab_tmp;
1843 auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
1846 ab.first = std::move( std::get< 0 >( ab_tmp ) );
1847 ab.second = std::move( std::get< 1 >( ab_tmp ) );
1854 * @brief Signature class for marshalling std::vector template type
1856 * This marshals container's content as DBUS a ascii character type code.
1858 template < typename A >
1859 struct signature< std::vector< A > >
1862 * @brief Returns name of type marshalled, for informative purposes
1864 static std::string name()
1866 return "vector<" + signature< A >::name() + ">";
1870 * @brief Returns DBUS' signature of type marshalled
1872 static std::string sig()
1874 return "a" + signature< A >::sig();
1878 * @brief Marshals value v as marshalled type into message
1880 static void set( const DBusWrapper::MessageIterPtr &iter, const std::vector< A >& v )
1882 auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1886 signature< A >::set( lst, a );
1891 * @brief Marshals value from marshalled type into variable v
1893 static bool get( const DBusWrapper::MessageIterPtr &iter, std::vector< A >& v )
1895 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1896 if (!s) return false;
1899 while( signature< A >::get( s, a ) )
1900 v.push_back( std::move( a ) );
1907 * @brief Signature class for marshalling std::array template type
1909 * This marshals container's content as DBUS a ascii character type code.
1911 template < typename A, size_t N >
1912 struct signature< std::array< A, N > >
1915 * @brief Returns name of type marshalled, for informative purposes
1917 static std::string name()
1919 return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
1923 * @brief Returns DBUS' signature of type marshalled
1925 static std::string sig()
1927 return "a" + signature< A >::sig();
1931 * @brief Marshals value v as marshalled type into message
1933 static void set( const DBusWrapper::MessageIterPtr &iter, const std::array< A, N >& v )
1935 auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', signature< A >::sig());
1939 signature< A >::set( lst, a );
1944 * @brief Marshals value from marshalled type into variable v
1946 static bool get( const DBusWrapper::MessageIterPtr &iter, std::array< A, N >& v )
1948 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
1953 if( !signature< A >::get( s, a ) )
1961 * @brief Signature class for marshalling EldbusVariant type
1963 * This marshals variant's content as DBUS v ascii character type code.
1965 template < typename A >
1966 struct signature< EldbusVariant< A > >
1969 * @brief Returns name of type marshalled, for informative purposes
1971 static std::string name()
1973 return "variant<" + signature< A >::name() + ">";
1977 * @brief Returns DBUS' signature of type marshalled
1979 static std::string sig()
1985 * @brief Marshals value v as marshalled type into message
1987 static void set( const DBusWrapper::MessageIterPtr &iter, const EldbusVariant< A >& v )
1989 set( iter, v.value );
1993 * @brief Marshals value v as marshalled type into message
1995 static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
1997 auto var = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'v', signature< A >::sig());
1998 signature< A >::set( var, v );
2002 * @brief Marshals value from marshalled type into variable v
2004 static bool get( const DBusWrapper::MessageIterPtr &iter, EldbusVariant< A >& v )
2006 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'v' );
2009 return signature< A >::get( s, v.value );
2014 * @brief Signature class for marshalling std::unordered_map template type
2016 * This marshals container's content as DBUS {} ascii character type code.
2017 * Note, that library doesnt check, if the key is basic type, as DBUS
2018 * specification mandates.
2019 * User can always exchange std::unordered_map for std::map and the reverse.
2020 * User can receive such values as std::vector of std::pair<key, value> values.
2021 * Order of such values is unspecified.
2023 template < typename A, typename B >
2024 struct signature< std::unordered_map< A, B > >
2027 * @brief Returns name of type marshalled, for informative purposes
2029 static std::string name()
2031 return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2035 * @brief Returns DBUS' signature of type marshalled
2037 static std::string sig()
2039 return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2043 * @brief Marshals value v as marshalled type into message
2045 static void set( const DBusWrapper::MessageIterPtr &iter, const std::unordered_map< A, B >& v )
2047 auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2048 auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2052 signature< std::pair< A, B > >::set( lst, a, true );
2057 * @brief Marshals value from marshalled type into variable v
2059 static bool get( const DBusWrapper::MessageIterPtr &iter, std::unordered_map< A, B >& v )
2061 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2065 std::pair< A, B > a;
2066 while( signature< std::pair< A, B > >::get( s, a ) )
2067 v.insert( std::move( a ) );
2073 * @brief Signature class for marshalling std::unordered_map template type
2075 * This marshals container's content as DBUS {} ascii character type code.
2076 * Note, that library doesnt check, if the key is basic type, as DBUS
2077 * specification mandates.
2078 * User can always exchange std::unordered_map for std::map and the reverse.
2079 * User can receive such values as std::vector of std::pair<key, value> values.
2080 * Order of such values is unspecified.
2082 template < typename A, typename B >
2083 struct signature< std::map< A, B > >
2086 * @brief Returns name of type marshalled, for informative purposes
2088 static std::string name()
2090 return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
2094 * @brief Returns DBUS' signature of type marshalled
2096 static std::string sig()
2098 return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2102 * @brief Marshals value v as marshalled type into message
2104 static void set( const DBusWrapper::MessageIterPtr &iter, const std::map< A, B >& v )
2106 auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
2107 auto lst = DBUS_W->eldbus_message_iter_container_new_impl( iter, 'a', sig);
2111 signature< std::pair< A, B > >::set( lst, a, true );
2116 * @brief Marshals value from marshalled type into variable v
2118 static bool get( const DBusWrapper::MessageIterPtr &iter, std::map< A, B >& v )
2120 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl( iter, 'a' );
2123 std::pair< A, B > a;
2124 while( signature< std::pair< A, B > >::get( s, a ) )
2125 v.insert( std::move( a ) );
2131 * @brief Signature helper class for marshalling const reference types
2133 template < typename A >
2134 struct signature< const A& >
2137 * @brief Returns name of type marshalled, for informative purposes
2139 static std::string name()
2141 return "const " + signature< A >::name() + "&";
2145 * @brief Returns DBUS' signature of type marshalled
2147 static std::string sig()
2149 return signature< A >::sig();
2153 * @brief Marshals value v as marshalled type into message
2155 static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2157 signature< A >::set( iter, v );
2161 * @brief Marshals value from marshalled type into variable v
2163 static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2165 signature< A >::get( iter, v );
2170 * @brief Signature helper class for marshalling reference types
2172 template < typename A >
2173 struct signature< A& >
2176 * @brief Returns name of type marshalled, for informative purposes
2178 static std::string name()
2180 return signature< A >::name() + "&";
2184 * @brief Returns DBUS' signature of type marshalled
2186 static std::string sig()
2188 return signature< A >::sig();
2192 * @brief Marshals value v as marshalled type into message
2194 static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2196 signature< A >::set( iter, v );
2200 * @brief Marshals value from marshalled type into variable v
2202 static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2204 signature< A >::get( iter, v );
2209 * @brief Signature helper class for marshalling const types
2211 template < typename A >
2212 struct signature< const A >
2215 * @brief Returns name of type marshalled, for informative purposes
2217 static std::string name()
2219 return "const " + signature< A >::name();
2223 * @brief Returns DBUS' signature of type marshalled
2225 static std::string sig()
2227 return signature< A >::sig();
2231 * @brief Marshals value v as marshalled type into message
2233 static void set( const DBusWrapper::MessageIterPtr &iter, const A& v )
2235 signature< A >::set( iter, v );
2239 * @brief Marshals value from marshalled type into variable v
2241 static void get( const DBusWrapper::MessageIterPtr &iter, A& v )
2243 signature< A >::get( iter, v );
2248 using CallId = DBusWrapper::CallId;
2250 template < typename ValueType >
2251 ValueType unpackValues( CallId callId, const DBusWrapper::MessagePtr &msg )
2253 auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, false );
2258 if( !signature< ValueType >::get( iter, r ) )
2260 DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
2261 r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
2262 DBUS_W->eldbus_message_signature_get_impl( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
2267 r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
2272 inline void packValues_helper( const DBusWrapper::MessageIterPtr& ) {}
2274 template < typename A, typename... ARGS >
2275 void packValues_helper( const DBusWrapper::MessageIterPtr &iter, A&& a, ARGS&&... r )
2277 signature< A >::set( iter, std::forward< A >( a ) );
2278 packValues_helper( iter, std::forward< ARGS >( r )... );
2281 template < typename... ARGS >
2282 void packValues( CallId callId, const DBusWrapper::MessagePtr &msg, ARGS&&... r )
2284 auto iter = DBUS_W->eldbus_message_iter_get_impl( msg, true );
2285 packValues_helper( iter, std::forward< ARGS >( r )... );
2288 template < typename >
2290 template < typename R, typename... ARGS >
2291 struct ReturnType< R( ARGS... ) >
2296 template < typename R, typename... ARGS >
2297 struct ReturnType< std::function< R( ARGS... ) > >
2307 template < int N, int... S >
2308 struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
2312 template < int... S >
2313 struct sequence_gen< 0, S... >
2315 typedef sequence< S... > type;
2318 template < typename C, typename... ARGS >
2321 const std::function< C >& c;
2322 const std::tuple< ARGS... >& args;
2324 template < int... S >
2325 auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
2327 return c( std::get< S >( args )... );
2329 auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2331 return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2335 template < typename C, typename A, typename... ARGS >
2336 struct apply_helper_2
2338 const std::function< C >& c;
2340 const std::tuple< ARGS... >& args;
2342 template < int... S >
2343 auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
2345 return c( a, std::get< S >( args )... );
2347 auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
2349 return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
2353 template < typename C, typename... ARGS >
2354 auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2356 apply_helper< C, ARGS... > ah{c, args};
2357 return ah.apply_1();
2360 template < typename C, typename D, typename... ARGS >
2361 auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
2363 apply_helper_2< C, D, ARGS... > ah{c, d, args};
2364 return ah.apply_1();
2367 struct ConnectionState
2369 DBusWrapper::ConnectionPtr connection;
2370 DBusWrapper::ObjectPtr object;
2371 DBusWrapper::ProxyPtr proxy, propertiesProxy;
2374 template < typename RETTYPE, typename... ARGS >
2375 RETTYPE call( CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
2377 const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2380 DBUS_DEBUG( "call %d: not initialized", callId.id );
2381 return Error{"not initialized"};
2384 DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
2385 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2388 DBUS_DEBUG( "call %d: failed", callId.id );
2389 return Error{"failed to create message"};
2392 detail::packValues( callId, msg, args... );
2393 auto reply = DBUS_W->eldbus_proxy_send_and_block_impl( proxy, msg );
2394 DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
2397 DBUS_DEBUG( "call %d: failed", callId.id );
2398 return Error{"eldbus returned null as reply"};
2400 std::string errname, errmsg;
2401 if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2403 DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2404 return Error{errname + ": " + errmsg};
2406 DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2407 DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2408 return detail::unpackValues< RETTYPE >( callId, reply );
2411 template < typename RETTYPE, typename... ARGS >
2412 void asyncCall( CallId callId, const ConnectionState &connectionState,
2413 bool property, const std::string& funcName,
2414 std::function< void( RETTYPE ) > callback, const ARGS&... args )
2416 const auto &proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2419 DBUS_DEBUG( "call %d: not initialized", callId.id );
2420 callback( Error{"not initialized"} );
2424 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl( proxy, funcName );
2427 DBUS_DEBUG( "call %d: failed", callId.id );
2428 callback( Error{"failed to create message"} );
2432 detail::packValues( callId, msg, args... );
2433 auto pending = DBUS_W->eldbus_proxy_send_impl( proxy, msg, [callback, callId, proxy]( const DBusWrapper::MessagePtr &reply ) {
2434 DBUS_DEBUG( "call %d: calling done", callId.id );
2437 DBUS_DEBUG( "call %d: failed", callId.id );
2438 callback( Error{"eldbus returned null as reply"} );
2442 std::string errname, errmsg;
2443 if( DBUS_W->eldbus_message_error_get_impl( reply, errname, errmsg ) )
2445 DBUS_DEBUG( "call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str() );
2446 callback( Error{errname + ": " + errmsg} );
2450 DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id,
2451 DBUS_W->eldbus_message_signature_get_impl( reply ).c_str() );
2452 callback( detail::unpackValues< RETTYPE >( callId, reply ) );
2459 DBUS_DEBUG( "call %d: call sent", callId.id );
2463 DBUS_DEBUG( "call %d: failed to send call", callId.id );
2464 callback( Error{"failed to send call"} );
2468 inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2470 DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2473 inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2475 DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2478 inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2479 const std::string& propertyName )
2481 DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
2484 using StringStorage = DBusWrapper::StringStorage;
2486 template < typename A, typename... ARGS >
2487 struct EldbusArgGenerator_Helper
2489 static void add( std::vector< std::pair<std::string, std::string> >& r )
2492 auto sig = signature< A >::sig();
2493 bart_assert( !sig.empty() );
2494 auto name = "p" + std::to_string( s + 1 );
2495 r.push_back({ std::move(sig), std::move(name) });
2496 EldbusArgGenerator_Helper<ARGS...>::add( r );
2501 struct EldbusArgGenerator_Helper< void >
2503 static void add( std::vector< std::pair<std::string, std::string> >& )
2509 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2511 static void add( std::vector< std::pair<std::string, std::string> >& )
2516 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2518 static void add( std::vector< std::pair<std::string, std::string> >& )
2523 template < typename... ARGS >
2524 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2526 static void add( std::vector< std::pair<std::string, std::string> >& r )
2528 EldbusArgGenerator_Helper< ARGS..., void >::add( r );
2532 template < typename RetType >
2533 struct dbus_interface_return_type_traits
2535 using type = ValueOrError< RetType >;
2538 template < typename... ARGS >
2539 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2541 using type = ValueOrError< ARGS... >;
2544 template < typename T >
2545 struct dbus_interface_traits;
2546 template < typename RetType, typename... ARGS >
2547 struct dbus_interface_traits< RetType( ARGS... ) >
2549 using Ret = typename dbus_interface_return_type_traits< RetType >::type;
2550 using SyncCB = std::function< Ret( ARGS... ) >;
2551 using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
2552 using VEArgs = ValueOrError< ARGS... >;
2555 template < typename T >
2556 struct EldbusArgGenerator_Args;
2557 template < typename RetType, typename... ARGS >
2558 struct EldbusArgGenerator_Args< RetType( ARGS... ) >
2560 static std::string name()
2562 return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
2564 static std::vector< std::pair<std::string, std::string> > get()
2566 std::vector< std::pair<std::string, std::string> > tmp;
2567 EldbusArgGenerator_Helper< ARGS..., void >::add( tmp );
2572 template < typename T >
2573 struct EldbusArgGenerator_ReturnType;
2574 template < typename RetType, typename... ARGS >
2575 struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
2577 static std::string name()
2579 return signature< RetType >::name();
2581 static std::vector< std::pair<std::string, std::string> > get( )
2583 std::vector< std::pair<std::string, std::string> > tmp;
2584 EldbusArgGenerator_Helper< RetType, void >::add( tmp );
2589 template < typename T >
2590 struct EldbusArgGenerator_ReturnType;
2591 template < typename... ARGS >
2592 struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
2594 static std::string name()
2598 static std::vector< std::pair<std::string, std::string> > get( )
2606 using ConnectionType = DBusWrapper::ConnectionType;
2609 * @brief Class representing client's end of DBUS connection
2611 * Allows calling (synchronous and asynchronos) methods on selected interface
2612 * Allows (synchronous and asynchronos) setting / getting properties.
2613 * Allows registering signals.
2618 struct ConnectionInfo
2620 std::string interfaceName, busName, pathName;
2625 * @brief Default constructor, creates non-connected object.
2627 DBusClient() = default;
2630 * @brief Connects to dbus choosen by tp, using given arguments
2632 * @param bus_name name of the bus to connect to
2633 * @param path_name object's path
2634 * @param interface_name interface name
2636 DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2637 ConnectionType tp );
2640 * @brief Connects to dbus using connection conn
2642 * @param bus_name name of the bus to connect to
2643 * @param path_name object's path
2644 * @param interface_name interface name
2645 * @param conn connection object from getDBusConnectionByType call
2647 DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2648 const DBusWrapper::ConnectionPtr &conn = {} );
2651 * @brief Destructor object.
2653 * All signals added will be disconnected.
2654 * All asynchronous calls will be cancelled, their callback's will be called
2655 * with failure message.
2657 ~DBusClient() = default;
2658 DBusClient( const DBusClient& ) = delete;
2659 DBusClient( DBusClient&& ) = default;
2661 DBusClient& operator=( DBusClient&& ) = default;
2662 DBusClient& operator=( const DBusClient& ) = delete;
2665 * @brief bool operator
2667 * Returns true, if object is connected to DBUS
2669 explicit operator bool() const
2671 return bool( connectionState->proxy );
2675 * @brief Helper class for calling a method
2677 * Template type T defines both arguments sent to the method
2678 * and expected values. Receiving different values will be reported as
2679 * error. For example:
2680 * \code{.cpp} Method<int(float, float)> \endcode
2681 * defines method, which takes two arguments (two floats) and return
2682 * single value of type int.
2684 template < typename T >
2688 using RetType = typename detail::dbus_interface_traits< T >::Ret;
2689 const detail::ConnectionState &connectionState;
2690 std::string funcName;
2692 std::shared_ptr< ConnectionInfo > connectionInfo;
2696 * @brief Executes synchronous call on DBUS's method
2698 * The function returns ValueOrError<...> object, which
2699 * contains either received values or error message.
2701 * @param args arguments to pass to the method
2703 template < typename... ARGS >
2704 RetType call( const ARGS&... args )
2706 detail::CallId callId;
2707 detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2708 return detail::call< RetType >( callId, connectionState, false, funcName, args... );
2712 * @brief Executes asynchronous call on DBUS's method
2714 * The function calls callback with either received values or error message.
2716 * @param callback callback functor, which will be called with return value(s) or error message
2717 * @param args arguments to pass to the method
2719 template < typename... ARGS >
2720 void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
2722 detail::CallId callId;
2723 detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2724 detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
2729 * @brief Helper class for calling a property
2731 * Template type T defines type of the value hidden under property.
2732 * Note, that library automatically wraps both sent and received value into
2733 * DBUS's wrapper type.
2735 template < typename T >
2739 using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
2740 using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
2741 const detail::ConnectionState &connectionState;
2742 std::string propName;
2744 std::shared_ptr< ConnectionInfo > connectionInfo;
2748 * @brief executes synchronous get on property
2750 * The function returns ValueOrError<...> object, which
2751 * contains either received values or error message.
2755 detail::CallId callId;
2756 detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2757 auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
2759 return z.getError();
2760 return {std::get< 0 >( z.getValues() ).value};
2764 * @brief executes asynchronous get on property
2766 * The function calls callback with either received values or error message.
2768 * @param callback callback functor, which will be called with return value(s) or error message
2770 void asyncGet( std::function< void( RetType ) > callback )
2772 detail::CallId callId;
2773 detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2774 auto cc = [callback]( VariantRetType reply ) {
2776 callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
2778 callback( reply.getError() );
2780 detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
2784 * @brief executes synchronous set on property
2786 * The function returns ValueOrError<void> object, with
2787 * possible error message.
2789 ValueOrError< void > set( const T& r )
2791 detail::CallId callId;
2792 detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2793 EldbusVariant< T > variantValue{std::move( r )};
2794 return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
2798 * @brief executes asynchronous get on property
2800 * The function calls callback with either received values or error message.
2802 * @param callback callback functor, which will be called with return value(s) or error message
2804 void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
2806 detail::CallId callId;
2807 detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2808 EldbusVariant< T > variantValue{std::move( r )};
2809 detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
2814 * @brief Constructs Property<...> object for calling properties
2816 * The function constructs and returns proxy object for calling property.
2818 * @param propName property name to set and / or query
2820 template < typename PropertyType >
2821 Property< PropertyType > property( std::string propName )
2823 return Property< PropertyType >{*connectionState, std::move( propName ), info, connectionInfo};
2827 * @brief Constructs Method<...> object for calling methods
2829 * The function constructs and returns proxy object for calling method.
2831 * @param funcName function name to call
2833 template < typename MethodType >
2834 Method< MethodType > method( std::string funcName )
2836 return Method< MethodType >{*connectionState, std::move( funcName ), info, connectionInfo};
2840 * @brief Registers notification callback, when property has changed
2842 * The callback will be called with new value, when property's value has changed.
2843 * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2844 * there's no check for this.
2846 template < typename V >
2847 void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
2849 detail::CallId callId;
2850 detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
2851 DBUS_DEBUG( "call %d: adding property", callId.id );
2852 auto &cI = this->connectionInfo;
2853 DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
2854 [callback]( const _Eina_Value *newValue ) {
2856 if( !getFromEinaValue( newValue, &val ) )
2858 DBUS_DEBUG( "unable to get property's value" );
2866 * @brief Registers callback on the DBUS' signal
2868 * The function registers callback signalName. When signal comes, callback will be called.
2869 * Callback object will exists as long as signal is registered. You can unregister signal
2870 * by destroying DBusClient object.
2872 * @param signalName name of the signal to register
2873 * @param callback callback to call
2875 template < typename SignalType >
2876 void addSignal( std::string signalName, std::function< SignalType > callback )
2878 detail::CallId callId;
2879 detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
2880 DBUS_W->eldbus_proxy_signal_handler_add_impl( connectionState->proxy, signalName,
2881 [callId, callback, signalName]( const DBusWrapper::MessagePtr &msg ) -> void {
2882 std::string errname, aux;
2883 if( DBUS_W->eldbus_message_error_get_impl( msg, errname, aux ) )
2885 DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str() );
2888 DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl( msg ).c_str() );
2889 using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2890 auto params = detail::unpackValues< ParamsType >( callId, msg );
2893 DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
2898 detail::apply( callback, params.getValues() );
2902 DBUS_DEBUG( "unhandled exception" );
2910 std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2912 std::shared_ptr< ConnectionInfo > connectionInfo;
2914 static bool getFromEinaValue(const _Eina_Value *v, void *dst);
2919 * @brief Helper class describing DBUS's server interface
2922 class DBusInterfaceDescription
2924 friend class DBusServer;
2928 using MethodInfo = DBusWrapper::MethodInfo;
2929 using SignalInfo = DBusWrapper::SignalInfo;
2930 using PropertyInfo = DBusWrapper::PropertyInfo;
2931 using SignalId = DBusWrapper::SignalId;
2935 * @brief Creates empty interface description with given name
2937 * @param interfaceName name of the interface
2939 DBusInterfaceDescription( std::string interfaceName );
2942 * @brief adds new, synchronous method to the interface
2944 * When method memberName is called on DBUS, callback functor will be called
2945 * with values received from DBUS. callback won't be called, if method was
2946 * called with invalid signature. Value returned from functor (or error message)
2947 * will be marshalled back to the caller.
2949 * Template type T defines both arguments sent to the method
2950 * and expected values. Receiving different values will be reported as
2951 * error. For example:
2952 * \code{.cpp} Method<int(float, float)> \endcode
2953 * defines method, which takes two arguments (two floats) and return
2954 * single value of type int.
2956 * @param memberName name of the method
2957 * @param callback functor, which will be called
2959 template < typename T >
2960 void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
2962 detail::CallId callId;
2964 methods.push_back( std::move( mi ) );
2965 auto& z = methods.back();
2966 z.in = detail::EldbusArgGenerator_Args< T >::get( );
2967 z.out = detail::EldbusArgGenerator_ReturnType< T >::get( );
2968 z.memberName = memberName;
2969 DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2970 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2971 detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
2972 z.callback = construct< T >( callId, callback );
2977 * @brief adds new, synchronous property to the interface
2979 * When property memberName is called on DBUS, respective callback functor will be called
2980 * with values received from DBUS. callback won't be called, if method was
2981 * called with invalid signature. Value returned from functor (or error message)
2982 * will be marshalled back to the caller.
2984 * Template type T defines type of the value hidden under property.
2985 * Note, that library automatically wraps both sent and received value into
2986 * DBUS's wrapper type.
2988 * @param memberName name of the method
2989 * @param getter functor, which will be called when property is being read
2990 * @param setter functor, which will be called when property is being set
2992 template < typename T >
2993 void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
2995 properties.push_back( {} );
2996 auto& z = properties.back();
2997 z.memberName = memberName;
2998 z.typeSignature = detail::signature< T >::sig();
3001 detail::CallId getterId;
3002 z.getterId = getterId;
3003 DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
3004 z.getCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &dst ) -> std::string {
3007 auto v = detail::apply( getter, std::tuple<>{} );
3010 detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
3011 DBUS_DEBUG( "call %d: success", getterId.id );
3014 DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
3015 return v.getError().message;
3017 catch( std::exception& e )
3019 return std::string( "unhandled exception (" ) + e.what() + ")";
3023 return "unhandled exception";
3029 detail::CallId setterId;
3030 z.setterId = setterId;
3031 DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
3032 z.setCallback = [=]( const DBusWrapper::MessagePtr &src, const DBusWrapper::MessageIterPtr &src_iter ) -> std::string {
3033 std::tuple< T > value;
3034 auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl( src_iter );
3035 if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
3039 auto v = detail::apply( setter, std::move( value ) );
3042 DBUS_DEBUG( "call %d: success", setterId.id );
3045 DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
3046 return v.getError().message;
3048 catch( std::exception& e )
3050 return std::string( "unhandled exception (" ) + e.what() + ")";
3054 return "unhandled exception";
3057 DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
3058 src_signature.c_str(), detail::signature< T >::sig().c_str() );
3059 return "call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
3060 src_signature + "', expected '" + detail::signature< T >::sig() + "'";
3066 * @brief adds new signal to the interface
3068 * Template types ARGS defines values, which will be emited with the signal
3070 * @param memberName name of the method
3072 template < typename... ARGS >
3073 SignalId addSignal( const std::string& memberName )
3075 detail::CallId callId;
3076 signals.push_back( {} );
3077 auto& z = signals.back();
3078 z.memberName = memberName;
3079 z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( DBUS_W->Strings );
3081 DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
3082 return SignalId{callId};
3087 std::vector< MethodInfo > methods;
3088 std::vector< PropertyInfo > properties;
3089 std::vector< SignalInfo > signals;
3090 std::string interfaceName;
3092 template < typename T >
3093 std::function< DBusWrapper::MessagePtr( const DBusWrapper::MessagePtr &msg ) > construct( detail::CallId callId,
3094 typename detail::dbus_interface_traits< T >::SyncCB callback )
3096 using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
3097 return [=]( const DBusWrapper::MessagePtr &msg ) -> DBusWrapper::MessagePtr {
3098 DBUS_DEBUG( "call %d: entering", callId.id );
3099 DBusWrapper::MessagePtr ret = {};
3100 auto args = detail::unpackValues< VEArgs >( callId, msg );
3105 auto v = detail::apply( callback, std::move( args.getValues() ) );
3108 DBUS_DEBUG( "call %d: success", callId.id );
3109 ret = DBUS_W->eldbus_message_method_return_new_impl( msg );
3110 detail::packValues( callId, ret, v );
3114 DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
3115 ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message );
3118 catch( std::exception& e )
3120 auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
3121 DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
3122 ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", txt );
3126 DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
3127 ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
3132 std::ostringstream err;
3133 err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl( msg ) << "'";
3134 auto str = err.str();
3135 DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
3136 ret = DBUS_W->eldbus_message_error_new_impl( msg, "org.freedesktop.DBus.Error.InvalidArgs", str );
3145 * @brief Class representing server's end of DBUS connection
3147 * Allows listening (synchronously and asynchronosly) on methods on selected interface
3148 * Allows listening (synchronously and asynchronosly) on setting / getting properties.
3149 * Allows emiting signals.
3155 * @brief Constructs non-connected dbus server.
3157 DBusServer() = default;
3160 * @brief Constructs dbus server on either system or user dbus connection.
3162 DBusServer( ConnectionType tp );
3165 * @brief Constructs dbus server on connection from getDBusConnectionByType
3167 DBusServer( const DBusWrapper::ConnectionPtr &conn );
3172 * Destructor will properly destroy everything. Destructor will cancel
3175 ~DBusServer() = default;
3177 DBusServer( const DBusServer& ) = delete;
3178 DBusServer( DBusServer&& ) = default;
3180 DBusServer& operator=( DBusServer&& ) = default;
3181 DBusServer& operator=( const DBusServer& ) = delete;
3184 * @brief Registers interface on given path name
3186 * @param pathName path object to register interface on.
3190 void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
3193 * @brief Gets bus name of the current connection (must be connected)
3195 std::string getBusName() const;
3198 * @brief Returns connection object for this dbus server object
3200 * @return connection object
3202 DBusWrapper::ConnectionPtr getConnection();
3205 * @brief Emits signal
3207 * Emits signal based only on data passed to the function
3209 * @param signal identifier of the signal
3210 * @param args values to emit
3212 template < typename... ARGS >
3213 void emit2( const std::string& path, const std::string& interfaceName,
3214 const std::string& signalName, const ARGS&... args )
3216 auto msg = DBUS_W->eldbus_message_signal_new_impl( path, interfaceName, signalName );
3218 detail::packValues( id, msg, args... );
3219 DBUS_W->eldbus_connection_send_impl( connection, msg );
3223 * @brief Returns current object path, when handling call to property / method
3225 * User can call this function from inside callback used to handle property / method calls.
3226 * It will retrieve object's path used in the call. Note, that in asynchronous handling
3227 * of those calls user need to retrieve and store the current object / current connection
3228 * as the value will change at the moment user's callback handling will exit. For example:
3230 * DBusInterfaceDescription interface{"name"};
3231 * auto handler_later = [](std::function<void(void)> done_cb) {
3232 * // process something later on
3233 * DBusServer::getCurrentObjectPath(); // this will return empty string
3235 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3236 * DBusServer::getCurrentObjectPath(); // this will current object's path
3238 * // do some processing later on and call done_cb, when it's done
3239 * register_to_call_sometime_later_on(std::move(done_cb));
3243 static std::string getCurrentObjectPath() { return currentObjectPath; }
3246 * @brief Returns current connection object, when handling call to property / method
3248 * User can call this function from inside callback used to handle property / method calls.
3249 * It will retrieve object's path used in the call. Note, that in asynchronous handling
3250 * of those calls user need to retrieve and store the current object / current connection
3251 * as the value will change at the moment user's callback handling will exit. For example:
3253 * DBusInterfaceDescription interface{"name"};
3254 * auto handler_later = [](std::function<void(void)> done_cb) {
3255 * // process something later on
3256 * DBusServer::getCurrentObjectPath(); // this will return empty string
3258 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
3259 * DBusServer::getCurrentObjectPath(); // this will current object's path
3261 * // do some processing later on and call done_cb, when it's done
3262 * register_to_call_sometime_later_on(std::move(done_cb));
3266 static const DBusWrapper::ConnectionPtr &getCurrentConnection() { return currentConnection; }
3269 class CurrentObjectSetter
3272 CurrentObjectSetter( DBusWrapper::ConnectionPtr con, std::string path )
3274 currentObjectPath = std::move(path);
3275 currentConnection = std::move( con );
3277 ~CurrentObjectSetter()
3279 currentObjectPath = "";
3280 currentConnection = {};
3282 CurrentObjectSetter( const CurrentObjectSetter& ) = delete;
3283 CurrentObjectSetter( CurrentObjectSetter&& ) = delete;
3284 void operator=( const CurrentObjectSetter& ) = delete;
3285 void operator=( CurrentObjectSetter&& ) = delete;
3291 DBusWrapper::ConnectionPtr connection;
3292 struct DestructorObject {
3293 std::vector<std::function<void()>> destructors;
3294 ~DestructorObject() {
3295 for(auto &a : destructors) a();
3299 std::unique_ptr<DestructorObject> destructorObject { new DestructorObject() };
3300 static thread_local std::string currentObjectPath;
3301 static thread_local DBusWrapper::ConnectionPtr currentConnection;
3307 DBusWrapper::ConnectionPtr getDBusConnectionByType( ConnectionType tp );
3308 DBusWrapper::ConnectionPtr getDBusConnectionByName( const std::string& name );
3309 std::string getConnectionName( const DBusWrapper::ConnectionPtr& );
3316 template < size_t INDEX, typename... ARGS >
3317 inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
3319 return std::get< INDEX >( v.getValues() );
3322 template < size_t INDEX, typename... ARGS >
3323 inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
3325 return std::get< INDEX >( v.getValues() );
3330 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H