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/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 void DBus::requestBusName(const DBusWrapper::ConnectionPtr& conn, const std::string& bus)
174 DBUS_W->eldbus_name_request_impl(conn, bus);
177 void DBus::releaseBusName(const DBusWrapper::ConnectionPtr& conn, const std::string& bus)
179 DBUS_W->eldbus_name_release_impl(conn, bus);
182 bool DBus::DBusClient::getFromEinaValue(const _Eina_Value* v, void* dst)
184 return eina_value_get(const_cast<Eina_Value*>(v), dst);
187 static std::unique_ptr<DBusWrapper> InstalledWrapper;
189 struct DefaultDBusWrapper : public DBusWrapper
191 constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
197 ~DefaultDBusWrapper()
201 #define DEFINE_GS(name, eldbus_name, unref_call) \
202 static eldbus_name* get(const std::shared_ptr<name>& a) \
204 return static_cast<name##Impl*>(a.get())->Value; \
206 static eldbus_name* release(const std::shared_ptr<name>& a) \
208 auto z = static_cast<name##Impl*>(a.get())->Value; \
209 static_cast<name##Impl*>(a.get())->Value = nullptr; \
212 template<typename... ARGS> \
213 static std::shared_ptr<name> create(const eldbus_name* v, ARGS&&... args) \
215 return std::make_shared<name##Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
218 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
219 struct name##Impl : public name \
221 eldbus_name* Value = nullptr; \
222 bool EraseOnExit = false; \
223 name##Impl(eldbus_name* Value, bool EraseOnExit = false): Value(Value), \
224 EraseOnExit(EraseOnExit) \
229 if(EraseOnExit && Value) \
235 DEFINE_GS(name, eldbus_name, unref_call)
237 struct ConnectionImpl : public Connection
239 Eldbus_Connection* Value = nullptr;
240 bool EraseOnExit = false;
241 ConnectionImpl(Eldbus_Connection* Value, bool EraseOnExit = false)
243 EraseOnExit(EraseOnExit)
251 if(EraseOnExit && Value)
253 eldbus_connection_unref(Value);
256 ecore_event_shutdown();
260 struct MessageIterImpl : public MessageIter
262 Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
263 bool EraseOnExit = false;
264 MessageIterImpl(Eldbus_Message_Iter* Value, Eldbus_Message_Iter* Parent, bool EraseOnExit = false)
267 EraseOnExit(EraseOnExit)
273 if(EraseOnExit && Value && Parent)
275 eldbus_message_iter_container_close(Parent, Value);
280 DEFINE_GS(Connection, Eldbus_Connection, )
281 DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
282 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref(Value))
283 DEFINE_TYPE(Proxy, Eldbus_Proxy, )
284 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref(Value))
285 DEFINE_TYPE(Pending, Eldbus_Pending, )
286 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
289 std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string& addr) override
292 auto p = eldbus_address_connection_get(addr.c_str());
293 auto w = create(p, true);
298 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
299 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, type src) override \
301 eldbus_message_iter_arguments_append(get(it), #sig, src); \
303 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, type& dst) override \
305 return eldbus_message_iter_get_and_next(get(it), (#sig)[0], &dst); \
309 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
310 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
311 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
312 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
313 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
314 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
315 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
316 eldbus_message_iter_arguments_append_impl_basic(double, d)
319 #undef eldbus_message_iter_arguments_append_impl_basic
321 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, bool src) override
323 eldbus_message_iter_arguments_append(get(it), "b", src ? 1 : 0);
326 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, bool& dst) override
329 auto z = eldbus_message_iter_get_and_next(get(it), 'b', &q);
334 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const std::string& src) override
336 eldbus_message_iter_arguments_append(get(it), "s", src.c_str());
339 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, std::string& dst) override
343 if(!eldbus_message_iter_get_and_next(iter, 's', &q))
345 if(!eldbus_message_iter_get_and_next(iter, 'o', &q))
354 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const ObjectPath& src) override
356 eldbus_message_iter_arguments_append(get(it), "o", src.value.c_str());
359 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, ObjectPath& dst) override
362 if(!eldbus_message_iter_get_and_next(get(it), 'o', &q))
370 MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr& it, int type, const std::string& sig) override
372 auto z = eldbus_message_iter_container_new(get(it), type, !sig.empty() ? sig.c_str() : NULL);
373 return create(z, get(it), true);
376 MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr& it, int type) override
378 Eldbus_Message_Iter* entry;
379 if(!eldbus_message_iter_get_and_next(get(it), type, &entry))
383 return create(entry, get(it), false);
386 MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr& msg, bool) override
388 return create(eldbus_message_iter_get(get(msg)), nullptr, false);
391 MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr& proxy, const std::string& funcName)
393 return create(eldbus_proxy_method_call_new(get(proxy), funcName.c_str()));
396 MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr& proxy, const MessagePtr& msg) override
398 return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT));
401 bool eldbus_message_error_get_impl(const MessagePtr& msg, std::string& name, std::string& text) override
403 const char *errname, *errmsg;
404 if(eldbus_message_error_get(get(msg), &errname, &errmsg))
413 std::string eldbus_message_signature_get_impl(const MessagePtr& msg) override
415 return eldbus_message_signature_get(get(msg));
418 static void callAsyncCb(void* data, const Eldbus_Message* msg, Eldbus_Pending* pending)
420 auto d = static_cast<SendCallback*>(data);
421 (*d)(create(msg, false));
424 static void pendingFreeCb(void* data, const void*)
426 auto d = static_cast<SendCallback*>(data);
430 static void listenerCallbackFree(void* data, const void*)
432 auto d = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
436 PendingPtr eldbus_proxy_send_impl(const ProxyPtr& proxy, const MessagePtr& msg, const SendCallback& callback) override
438 auto cb = new SendCallback{callback};
439 auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT);
442 eldbus_pending_free_cb_add(pending, pendingFreeCb, cb);
448 return create(pending, false);
451 std::string eldbus_proxy_interface_get_impl(const ProxyPtr& proxy) override
453 return eldbus_proxy_interface_get(get(proxy));
456 static void listenerCallback(void* data, const Eldbus_Message* msg)
458 auto p = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
462 void eldbus_proxy_signal_handler_add_impl(const ProxyPtr& proxy, const std::string& member, const std::function<void(const MessagePtr&)>& cb) override
464 auto tmp = new std::function<void(const Eldbus_Message* msg)>{
465 [cb](const Eldbus_Message* msg) {
466 cb(create(msg, false));
468 auto handler = eldbus_proxy_signal_handler_add(get(proxy), member.c_str(), listenerCallback, tmp);
471 eldbus_proxy_free_cb_add(get(proxy), listenerCallbackFree, tmp);
479 std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr& iter) override
481 return eldbus_message_iter_signature_get(get(iter));
484 MessagePtr eldbus_message_method_return_new_impl(const MessagePtr& msg) override
486 return create(eldbus_message_method_return_new(get(msg)));
489 MessagePtr eldbus_message_error_new_impl(const MessagePtr& msg, const std::string& err, const std::string& txt) override
491 return create(eldbus_message_error_new(get(msg), err.c_str(), txt.c_str()));
494 PendingPtr eldbus_connection_send_impl(const ConnectionPtr& conn, const MessagePtr& msg) override
496 return create(eldbus_connection_send(get(conn), get(msg), NULL, NULL, -1));
499 MessagePtr eldbus_message_signal_new_impl(const std::string& path, const std::string& iface, const std::string& name) override
501 return create(eldbus_message_signal_new(path.c_str(), iface.c_str(), name.c_str()));
504 MessagePtr eldbus_message_ref_impl(const MessagePtr& msg) override
506 return create(eldbus_message_ref(get(msg)), true);
509 ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override
511 Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
515 case ConnectionType::SYSTEM:
517 eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
520 case ConnectionType::SESSION:
522 eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
527 auto p = eldbus_connection_get(eldbusType);
530 DALI_LOG_ERROR("cannot get dbus connection\n");
533 auto w = create(p, true);
537 std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr& conn) override
539 return eldbus_connection_unique_name_get(get(conn));
542 ObjectPtr eldbus_object_get_impl(const ConnectionPtr& conn, const std::string& bus, const std::string& path) override
544 return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str()), true);
547 ProxyPtr eldbus_proxy_get_impl(const ObjectPtr& obj, const std::string& interface) override
549 return create(eldbus_proxy_get(get(obj), interface.c_str()), false);
552 ProxyPtr eldbus_proxy_copy_impl(const ProxyPtr& ptr) override
554 return create(get(ptr), false);
557 void eldbus_name_request_impl(const ConnectionPtr& conn, const std::string& bus) override
559 eldbus_name_request(get(conn), bus.c_str(), ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, nullptr, nullptr);
562 void eldbus_name_release_impl(const ConnectionPtr& conn, const std::string& bus) override
564 eldbus_name_release(get(conn), bus.c_str(), nullptr, nullptr);
567 struct Implementation
569 Eldbus_Service_Interface_Desc dsc;
570 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
571 std::vector<Eldbus_Method> methods;
572 std::vector<Eldbus_Signal> signals;
573 std::vector<Eldbus_Property> properties;
575 std::unordered_map<std::string, DBusWrapper::MethodInfo> methodsMap;
576 std::unordered_map<std::string, DBusWrapper::PropertyInfo> propertiesMap;
577 std::unordered_map<unsigned int, DBusWrapper::SignalInfo> signalsMap;
579 DBusWrapper::ConnectionWeakPtr connection;
582 static std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<Implementation>> globalEntries;
583 static std::mutex globalEntriesMutex;
587 #define EINA_FALSE static_cast<Eina_Bool>(0)
588 #define EINA_TRUE static_cast<Eina_Bool>(1)
590 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)
592 Implementation* impl = nullptr;
594 std::lock_guard<std::mutex> lock(globalEntriesMutex);
595 auto it = globalEntries.find(iface);
596 if(it != globalEntries.end())
598 impl = it->second.get();
606 auto it = impl->propertiesMap.find(propertyName);
607 if(it == impl->propertiesMap.end() || !it->second.getCallback)
612 auto connection = impl->connection.lock();
618 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
619 auto reply = it->second.getCallback(create(message, false), create(iter, nullptr, false));
624 *error = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
632 static Eldbus_Message* property_set_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message)
634 Implementation* impl = nullptr;
636 std::lock_guard<std::mutex> lock(globalEntriesMutex);
637 auto it = globalEntries.find(iface);
638 if(it != globalEntries.end())
640 impl = it->second.get();
645 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
648 auto it = impl->propertiesMap.find(propertyName);
649 if(it == impl->propertiesMap.end() || !it->second.setCallback)
651 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown setter");
654 auto connection = impl->connection.lock();
657 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
661 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
662 auto reply = it->second.setCallback(create(message, false), create(iter, nullptr, false));
664 Eldbus_Message* ret = nullptr;
667 ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
671 ret = eldbus_message_method_return_new(message);
676 static Eldbus_Message* method_callback(const Eldbus_Service_Interface* iface, const Eldbus_Message* message)
678 Implementation* impl = nullptr;
680 std::lock_guard<std::mutex> lock(globalEntriesMutex);
681 auto it = globalEntries.find(iface);
682 if(it != globalEntries.end())
683 impl = it->second.get();
687 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
690 std::string memberName = eldbus_message_member_get(message);
691 auto it = impl->methodsMap.find(memberName);
692 if(it == impl->methodsMap.end())
694 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown method");
697 auto connection = impl->connection.lock();
700 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
703 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
704 auto reply = it->second.callback(create(message));
705 return release(reply);
708 void add_interface_impl(bool fallback,
709 const std::string& pathName,
710 const ConnectionPtr& connection,
711 std::vector<std::function<void()>>& destructors,
712 const std::string& interfaceName,
713 std::vector<MethodInfo>& dscrMethods,
714 std::vector<PropertyInfo>& dscrProperties,
715 std::vector<SignalInfo>& dscrSignals) override
717 std::vector<Eldbus_Method> methods;
718 std::vector<Eldbus_Signal> signals;
719 std::vector<Eldbus_Property> properties;
720 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
721 std::unordered_map<std::string, DBus::DBusInterfaceDescription::MethodInfo> methodsMap;
722 std::unordered_map<std::string, DBus::DBusInterfaceDescription::PropertyInfo> propertiesMap;
723 std::unordered_map<unsigned int, DBus::DBusInterfaceDescription::SignalInfo> signalsMap;
725 DBUS_DEBUG("interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName(connection).c_str());
726 auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>>& input) {
727 argsInfos.push_back({});
728 auto& dst = argsInfos.back();
731 auto a = Strings.add(s.first);
732 auto b = Strings.add(s.second);
733 dst.push_back({a, b});
735 dst.push_back({nullptr, nullptr});
738 for(auto& ee : dscrMethods)
740 auto key = ee.memberName;
741 DBUS_DEBUG("adding method %s", ee.memberName.c_str());
744 DBUS_DEBUG("in %s '%s'", r.first.c_str(), r.second.c_str());
746 for(auto& r : ee.out)
748 DBUS_DEBUG("out %s '%s'", r.first.c_str(), r.second.c_str());
750 auto& e = (methodsMap[key] = std::move(ee));
751 methods.push_back({});
752 auto& m = methods.back();
753 m.member = e.memberName.c_str();
754 m.in = makeArgInfo(e.in);
755 m.out = makeArgInfo(e.out);
756 m.cb = method_callback;
759 for(auto& ee : dscrProperties)
761 auto key = ee.memberName;
762 DBUS_DEBUG("adding property %s", ee.memberName.c_str());
763 auto& e = (propertiesMap[key] = std::move(ee));
764 properties.push_back({});
765 auto& m = properties.back();
766 m.name = e.memberName.c_str();
767 m.type = e.typeSignature.c_str();
768 m.get_func = e.getCallback ? property_get_callback : nullptr;
769 m.set_func = e.setCallback ? property_set_callback : nullptr;
773 dscrProperties.clear();
776 methods.push_back({nullptr, nullptr, nullptr, nullptr, 0});
777 signals.push_back({nullptr, nullptr, 0});
778 properties.push_back({nullptr, nullptr, nullptr, nullptr, 0});
780 auto impl = std::unique_ptr<Implementation>(new Implementation{
781 {interfaceName.c_str(),
787 std::move(argsInfos),
790 std::move(properties),
791 std::move(methodsMap),
792 std::move(propertiesMap),
793 std::move(signalsMap),
797 std::lock_guard<std::mutex> lock(globalEntriesMutex);
798 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);
800 globalEntries[v] = std::move(impl);
801 DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
802 destructors.push_back([=]() {
803 DBUS_DEBUG("unregistering interface %p", v);
805 std::lock_guard<std::mutex> lock(globalEntriesMutex);
806 globalEntries.erase(v);
808 eldbus_service_interface_unregister(v);
813 static void listenerEventChangedCallback(void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event)
815 auto p = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
816 (*p)(static_cast<Eldbus_Proxy_Event_Property_Changed*>(event));
819 static void ProxyEventCallbackDelCb(void* data, const void* obj)
821 auto d = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
825 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
827 auto callbackLambdaPtr = new std::function<void(Eldbus_Proxy_Event_Property_Changed * epc)>{
828 [cb, name, interface](Eldbus_Proxy_Event_Property_Changed* ev) {
829 const char* ifc = eldbus_proxy_interface_get(ev->proxy);
830 if(ev->name && ev->name == name && ifc && interface == ifc)
836 eldbus_proxy_event_callback_add(p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, listenerEventChangedCallback, callbackLambdaPtr);
837 eldbus_proxy_free_cb_add(p, ProxyEventCallbackDelCb, callbackLambdaPtr);
841 std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<DefaultDBusWrapper::Implementation>> DefaultDBusWrapper::globalEntries;
842 std::mutex DefaultDBusWrapper::globalEntriesMutex;
844 DBusWrapper* DBusWrapper::Installed()
846 if(!InstalledWrapper)
848 InstalledWrapper.reset(new DefaultDBusWrapper);
850 return InstalledWrapper.get();
853 void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
855 InstalledWrapper = std::move(w);