2 * Copyright 2019 Samsung Electronics Co., Ltd
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <dali/internal/accessibility/bridge/accessibility-common.h>
19 #include <dali/internal/accessibility/bridge/dbus.h>
26 #include <Ecore_Input.h>
30 #include <dali/public-api/dali-adaptor-common.h>
32 #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
36 #define EINA_TRUE static_cast<Eina_Bool>(1)
37 #define EINA_FALSE static_cast<Eina_Bool>(0)
39 //#define DBUS_DEBUG(...) do { DBus::debugPrint(__FILE__, __LINE__, __VA_ARGS__); } while (0)
41 std::atomic<unsigned int> DBus::detail::CallId::LastId{0};
42 static std::function<void(const char*, size_t)> debugPrinter;
43 static std::mutex debugLock;
45 thread_local std::string DBus::DBusServer::currentObjectPath;
46 thread_local DBusWrapper::ConnectionPtr DBus::DBusServer::currentConnection;
48 void DBus::setDebugPrinter(std::function<void(const char*, size_t)> printer)
50 std::lock_guard<std::mutex> lock(debugLock);
51 debugPrinter = std::move(printer);
54 void DBus::debugPrint(const char* file, size_t line, const char* format, ...)
56 std::function<void(const char*, size_t)> debugPrintFunc;
58 std::lock_guard<std::mutex> lock(debugLock);
61 debugPrintFunc = debugPrinter;
63 std::vector<char> buf(4096);
67 offset = snprintf(buf.data(), buf.size(), "%s:%u: ", file, static_cast<unsigned int>(line));
70 if(static_cast<size_t>(offset) < buf.size())
72 buf.resize(offset + 1);
78 va_start(args, format);
79 int z = vsnprintf(buf.data() + offset, buf.size() - offset, format, args);
83 bool done = static_cast<size_t>(z) + static_cast<size_t>(offset) < buf.size();
84 buf.resize(static_cast<size_t>(z) + static_cast<size_t>(offset));
88 debugPrintFunc(buf.data(), buf.size());
91 DBusWrapper::ConnectionPtr DBus::getDBusConnectionByName(const std::string& name)
93 return DBUS_W->eldbus_address_connection_get_impl(name);
96 DBusWrapper::ConnectionPtr DBus::getDBusConnectionByType(ConnectionType connectionType)
98 return DBUS_W->eldbus_connection_get_impl(connectionType);
101 DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::string interfaceName, ConnectionType tp)
102 : DBusClient(std::move(busName), std::move(pathName), std::move(interfaceName), getDBusConnectionByType(tp))
106 DBus::DBusClient::DBusClient(std::string busName, std::string pathName, std::string interfaceName, const DBusWrapper::ConnectionPtr& conn)
109 connectionState->connection = getDBusConnectionByType(ConnectionType::SESSION);
111 connectionState->connection = conn;
114 if (!connectionState->connection)
116 DALI_LOG_ERROR("DBusClient connection is not ready\n");
120 connectionState->object = DBUS_W->eldbus_object_get_impl(connectionState->connection, busName.c_str(), pathName.c_str());
121 if(connectionState->object)
123 connectionState->proxy = DBUS_W->eldbus_proxy_get_impl(connectionState->object, interfaceName);
124 if(interfaceName != DBUS_INTERFACE_PROPERTIES)
126 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_get_impl(connectionState->object, DBUS_INTERFACE_PROPERTIES);
130 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_copy_impl(connectionState->proxy);
133 connectionInfo = std::make_shared<ConnectionInfo>();
134 connectionInfo->busName = std::move(busName);
135 connectionInfo->pathName = std::move(pathName);
136 connectionInfo->interfaceName = std::move(interfaceName);
139 DBus::DBusServer::DBusServer(ConnectionType tp)
140 : DBus::DBusServer(DBus::getDBusConnectionByType(tp))
144 DBus::DBusServer::DBusServer(const DBusWrapper::ConnectionPtr& conn)
147 connection = getDBusConnectionByType(ConnectionType::SESSION);
152 DBus::DBusInterfaceDescription::DBusInterfaceDescription(std::string interfaceName)
153 : interfaceName(std::move(interfaceName))
157 void DBus::DBusServer::addInterface(const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback)
159 DBUS_W->add_interface_impl(fallback, pathName, connection, destructorObject->destructors, dscr.interfaceName, dscr.methods, dscr.properties, dscr.signals);
162 std::string DBus::DBusServer::getBusName() const
164 return getConnectionName(connection);
167 std::string DBus::getConnectionName(const DBusWrapper::ConnectionPtr& c)
169 return DBUS_W->eldbus_connection_unique_name_get_impl(c);
172 bool DBus::DBusClient::getFromEinaValue(const _Eina_Value* v, void* dst)
174 return eina_value_get(const_cast<Eina_Value*>(v), dst);
177 static std::unique_ptr<DBusWrapper> InstalledWrapper;
179 struct DefaultDBusWrapper : public DBusWrapper
181 constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
187 ~DefaultDBusWrapper()
191 #define DEFINE_GS(name, eldbus_name, unref_call) \
192 static eldbus_name* get(const std::shared_ptr<name>& a) \
194 return static_cast<name##Impl*>(a.get())->Value; \
196 static eldbus_name* release(const std::shared_ptr<name>& a) \
198 auto z = static_cast<name##Impl*>(a.get())->Value; \
199 static_cast<name##Impl*>(a.get())->Value = nullptr; \
202 template<typename... ARGS> \
203 static std::shared_ptr<name> create(const eldbus_name* v, ARGS&&... args) \
205 return std::make_shared<name##Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
208 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
209 struct name##Impl : public name \
211 eldbus_name* Value = nullptr; \
212 bool EraseOnExit = false; \
213 name##Impl(eldbus_name* Value, bool EraseOnExit = false): Value(Value), \
214 EraseOnExit(EraseOnExit) \
219 if(EraseOnExit && Value) \
225 DEFINE_GS(name, eldbus_name, unref_call)
227 struct ConnectionImpl : public Connection
229 Eldbus_Connection* Value = nullptr;
230 bool EraseOnExit = false;
231 ConnectionImpl(Eldbus_Connection* Value, bool EraseOnExit = false)
233 EraseOnExit(EraseOnExit)
241 if(EraseOnExit && Value)
243 eldbus_connection_unref(Value);
246 ecore_event_shutdown();
250 struct MessageIterImpl : public MessageIter
252 Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
253 bool EraseOnExit = false;
254 MessageIterImpl(Eldbus_Message_Iter* Value, Eldbus_Message_Iter* Parent, bool EraseOnExit = false)
257 EraseOnExit(EraseOnExit)
263 if(EraseOnExit && Value && Parent)
265 eldbus_message_iter_container_close(Parent, Value);
270 DEFINE_GS(Connection, Eldbus_Connection, )
271 DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
272 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref(Value))
273 DEFINE_TYPE(Proxy, Eldbus_Proxy, )
274 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref(Value))
275 DEFINE_TYPE(Pending, Eldbus_Pending, )
276 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
279 std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string& addr) override
282 auto p = eldbus_address_connection_get(addr.c_str());
283 auto w = create(p, true);
288 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
289 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, type src) override \
291 eldbus_message_iter_arguments_append(get(it), #sig, src); \
293 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, type& dst) override \
295 return eldbus_message_iter_get_and_next(get(it), (#sig)[0], &dst); \
299 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
300 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
301 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
302 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
303 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
304 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
305 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
306 eldbus_message_iter_arguments_append_impl_basic(double, d)
309 #undef eldbus_message_iter_arguments_append_impl_basic
311 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, bool src) override
313 eldbus_message_iter_arguments_append(get(it), "b", src ? 1 : 0);
316 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, bool& dst) override
319 auto z = eldbus_message_iter_get_and_next(get(it), 'b', &q);
324 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const std::string& src) override
326 eldbus_message_iter_arguments_append(get(it), "s", src.c_str());
329 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, std::string& dst) override
333 if(!eldbus_message_iter_get_and_next(iter, 's', &q))
335 if(!eldbus_message_iter_get_and_next(iter, 'o', &q))
344 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const ObjectPath& src) override
346 eldbus_message_iter_arguments_append(get(it), "o", src.value.c_str());
349 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, ObjectPath& dst) override
352 if(!eldbus_message_iter_get_and_next(get(it), 'o', &q))
360 MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr& it, int type, const std::string& sig) override
362 auto z = eldbus_message_iter_container_new(get(it), type, !sig.empty() ? sig.c_str() : NULL);
363 return create(z, get(it), true);
366 MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr& it, int type) override
368 Eldbus_Message_Iter* entry;
369 if(!eldbus_message_iter_get_and_next(get(it), type, &entry))
373 return create(entry, get(it), false);
376 MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr& msg, bool) override
378 return create(eldbus_message_iter_get(get(msg)), nullptr, false);
381 MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr& proxy, const std::string& funcName)
383 return create(eldbus_proxy_method_call_new(get(proxy), funcName.c_str()));
386 MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr& proxy, const MessagePtr& msg) override
388 return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT));
391 bool eldbus_message_error_get_impl(const MessagePtr& msg, std::string& name, std::string& text) override
393 const char *errname, *errmsg;
394 if(eldbus_message_error_get(get(msg), &errname, &errmsg))
403 std::string eldbus_message_signature_get_impl(const MessagePtr& msg) override
405 return eldbus_message_signature_get(get(msg));
408 static void callAsyncCb(void* data, const Eldbus_Message* msg, Eldbus_Pending* pending)
410 auto d = static_cast<SendCallback*>(data);
411 (*d)(create(msg, false));
414 static void pendingFreeCb(void* data, const void*)
416 auto d = static_cast<SendCallback*>(data);
420 static void listenerCallbackFree(void* data, const void*)
422 auto d = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
426 PendingPtr eldbus_proxy_send_impl(const ProxyPtr& proxy, const MessagePtr& msg, const SendCallback& callback) override
428 auto cb = new SendCallback{callback};
429 auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT);
432 eldbus_pending_free_cb_add(pending, pendingFreeCb, cb);
438 return create(pending, false);
441 std::string eldbus_proxy_interface_get_impl(const ProxyPtr& proxy) override
443 return eldbus_proxy_interface_get(get(proxy));
446 static void listenerCallback(void* data, const Eldbus_Message* msg)
448 auto p = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
452 void eldbus_proxy_signal_handler_add_impl(const ProxyPtr& proxy, const std::string& member, const std::function<void(const MessagePtr&)>& cb) override
454 auto tmp = new std::function<void(const Eldbus_Message* msg)>{
455 [cb](const Eldbus_Message* msg) {
456 cb(create(msg, false));
458 auto handler = eldbus_proxy_signal_handler_add(get(proxy), member.c_str(), listenerCallback, tmp);
461 eldbus_proxy_free_cb_add(get(proxy), listenerCallbackFree, tmp);
469 std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr& iter) override
471 return eldbus_message_iter_signature_get(get(iter));
474 MessagePtr eldbus_message_method_return_new_impl(const MessagePtr& msg) override
476 return create(eldbus_message_method_return_new(get(msg)));
479 MessagePtr eldbus_message_error_new_impl(const MessagePtr& msg, const std::string& err, const std::string& txt) override
481 return create(eldbus_message_error_new(get(msg), err.c_str(), txt.c_str()));
484 PendingPtr eldbus_connection_send_impl(const ConnectionPtr& conn, const MessagePtr& msg) override
486 return create(eldbus_connection_send(get(conn), get(msg), NULL, NULL, -1));
489 MessagePtr eldbus_message_signal_new_impl(const std::string& path, const std::string& iface, const std::string& name) override
491 return create(eldbus_message_signal_new(path.c_str(), iface.c_str(), name.c_str()));
494 MessagePtr eldbus_message_ref_impl(const MessagePtr& msg) override
496 return create(eldbus_message_ref(get(msg)), true);
499 ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override
501 Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
505 case ConnectionType::SYSTEM:
507 eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
510 case ConnectionType::SESSION:
512 eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
517 auto p = eldbus_connection_get(eldbusType);
520 DALI_LOG_ERROR("cannot get dbus connection\n");
523 auto w = create(p, true);
527 std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr& conn) override
529 return eldbus_connection_unique_name_get(get(conn));
532 ObjectPtr eldbus_object_get_impl(const ConnectionPtr& conn, const std::string& bus, const std::string& path) override
534 return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str()), true);
537 ProxyPtr eldbus_proxy_get_impl(const ObjectPtr& obj, const std::string& interface) override
539 return create(eldbus_proxy_get(get(obj), interface.c_str()), false);
542 ProxyPtr eldbus_proxy_copy_impl(const ProxyPtr& ptr) override
544 return create(get(ptr), false);
547 struct Implementation
549 Eldbus_Service_Interface_Desc dsc;
550 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
551 std::vector<Eldbus_Method> methods;
552 std::vector<Eldbus_Signal> signals;
553 std::vector<Eldbus_Property> properties;
555 std::unordered_map<std::string, DBusWrapper::MethodInfo> methodsMap;
556 std::unordered_map<std::string, DBusWrapper::PropertyInfo> propertiesMap;
557 std::unordered_map<unsigned int, DBusWrapper::SignalInfo> signalsMap;
559 DBusWrapper::ConnectionWeakPtr connection;
562 static std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<Implementation>> globalEntries;
563 static std::mutex globalEntriesMutex;
567 #define EINA_FALSE static_cast<Eina_Bool>(0)
568 #define EINA_TRUE static_cast<Eina_Bool>(1)
570 static Eina_Bool property_get_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message, Eldbus_Message** error)
572 Implementation* impl = nullptr;
574 std::lock_guard<std::mutex> lock(globalEntriesMutex);
575 auto it = globalEntries.find(iface);
576 if(it != globalEntries.end())
578 impl = it->second.get();
586 auto it = impl->propertiesMap.find(propertyName);
587 if(it == impl->propertiesMap.end() || !it->second.getCallback)
592 auto connection = impl->connection.lock();
598 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
599 auto reply = it->second.getCallback(create(message, false), create(iter, nullptr, false));
604 *error = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
612 static Eldbus_Message* property_set_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message)
614 Implementation* impl = nullptr;
616 std::lock_guard<std::mutex> lock(globalEntriesMutex);
617 auto it = globalEntries.find(iface);
618 if(it != globalEntries.end())
620 impl = it->second.get();
625 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
628 auto it = impl->propertiesMap.find(propertyName);
629 if(it == impl->propertiesMap.end() || !it->second.setCallback)
631 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown setter");
634 auto connection = impl->connection.lock();
637 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
641 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
642 auto reply = it->second.setCallback(create(message, false), create(iter, nullptr, false));
644 Eldbus_Message* ret = nullptr;
647 ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
651 ret = eldbus_message_method_return_new(message);
656 static Eldbus_Message* method_callback(const Eldbus_Service_Interface* iface, const Eldbus_Message* message)
658 Implementation* impl = nullptr;
660 std::lock_guard<std::mutex> lock(globalEntriesMutex);
661 auto it = globalEntries.find(iface);
662 if(it != globalEntries.end())
663 impl = it->second.get();
667 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
670 std::string memberName = eldbus_message_member_get(message);
671 auto it = impl->methodsMap.find(memberName);
672 if(it == impl->methodsMap.end())
674 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown method");
677 auto connection = impl->connection.lock();
680 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
683 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
684 auto reply = it->second.callback(create(message));
685 return release(reply);
688 void add_interface_impl(bool fallback,
689 const std::string& pathName,
690 const ConnectionPtr& connection,
691 std::vector<std::function<void()>>& destructors,
692 const std::string& interfaceName,
693 std::vector<MethodInfo>& dscrMethods,
694 std::vector<PropertyInfo>& dscrProperties,
695 std::vector<SignalInfo>& dscrSignals) override
697 std::vector<Eldbus_Method> methods;
698 std::vector<Eldbus_Signal> signals;
699 std::vector<Eldbus_Property> properties;
700 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
701 std::unordered_map<std::string, DBus::DBusInterfaceDescription::MethodInfo> methodsMap;
702 std::unordered_map<std::string, DBus::DBusInterfaceDescription::PropertyInfo> propertiesMap;
703 std::unordered_map<unsigned int, DBus::DBusInterfaceDescription::SignalInfo> signalsMap;
705 DBUS_DEBUG("interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName(connection).c_str());
706 auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>>& input) {
707 argsInfos.push_back({});
708 auto& dst = argsInfos.back();
711 auto a = Strings.add(s.first);
712 auto b = Strings.add(s.second);
713 dst.push_back({a, b});
715 dst.push_back({nullptr, nullptr});
718 for(auto& ee : dscrMethods)
720 auto key = ee.memberName;
721 DBUS_DEBUG("adding method %s", ee.memberName.c_str());
724 DBUS_DEBUG("in %s '%s'", r.first.c_str(), r.second.c_str());
726 for(auto& r : ee.out)
728 DBUS_DEBUG("out %s '%s'", r.first.c_str(), r.second.c_str());
730 auto& e = (methodsMap[key] = std::move(ee));
731 methods.push_back({});
732 auto& m = methods.back();
733 m.member = e.memberName.c_str();
734 m.in = makeArgInfo(e.in);
735 m.out = makeArgInfo(e.out);
736 m.cb = method_callback;
739 for(auto& ee : dscrProperties)
741 auto key = ee.memberName;
742 DBUS_DEBUG("adding property %s", ee.memberName.c_str());
743 auto& e = (propertiesMap[key] = std::move(ee));
744 properties.push_back({});
745 auto& m = properties.back();
746 m.name = e.memberName.c_str();
747 m.type = e.typeSignature.c_str();
748 m.get_func = e.getCallback ? property_get_callback : nullptr;
749 m.set_func = e.setCallback ? property_set_callback : nullptr;
753 dscrProperties.clear();
756 methods.push_back({nullptr, nullptr, nullptr, nullptr, 0});
757 signals.push_back({nullptr, nullptr, 0});
758 properties.push_back({nullptr, nullptr, nullptr, nullptr, 0});
760 auto impl = std::unique_ptr<Implementation>(new Implementation{
761 {interfaceName.c_str(),
767 std::move(argsInfos),
770 std::move(properties),
771 std::move(methodsMap),
772 std::move(propertiesMap),
773 std::move(signalsMap),
777 std::lock_guard<std::mutex> lock(globalEntriesMutex);
778 auto v = fallback ? eldbus_service_interface_fallback_register(get(connection), pathName.c_str(), &impl->dsc) : eldbus_service_interface_register(get(connection), pathName.c_str(), &impl->dsc);
780 globalEntries[v] = std::move(impl);
781 DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
782 destructors.push_back([=]() {
783 DBUS_DEBUG("unregistering interface %p", v);
785 std::lock_guard<std::mutex> lock(globalEntriesMutex);
786 globalEntries.erase(v);
788 eldbus_service_interface_unregister(v);
793 static void listenerEventChangedCallback(void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event)
795 auto p = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
796 (*p)(static_cast<Eldbus_Proxy_Event_Property_Changed*>(event));
799 static void ProxyEventCallbackDelCb(void* data, const void* obj)
801 auto d = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
805 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
807 auto callbackLambdaPtr = new std::function<void(Eldbus_Proxy_Event_Property_Changed * epc)>{
808 [cb, name, interface](Eldbus_Proxy_Event_Property_Changed* ev) {
809 const char* ifc = eldbus_proxy_interface_get(ev->proxy);
810 if(ev->name && ev->name == name && ifc && interface == ifc)
816 eldbus_proxy_event_callback_add(p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, listenerEventChangedCallback, callbackLambdaPtr);
817 eldbus_proxy_free_cb_add(p, ProxyEventCallbackDelCb, callbackLambdaPtr);
821 std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<DefaultDBusWrapper::Implementation>> DefaultDBusWrapper::globalEntries;
822 std::mutex DefaultDBusWrapper::globalEntriesMutex;
824 DBusWrapper* DBusWrapper::Installed()
826 if(!InstalledWrapper)
828 InstalledWrapper.reset(new DefaultDBusWrapper);
830 return InstalledWrapper.get();
833 void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
835 InstalledWrapper = std::move(w);