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;
113 if(!connectionState->connection)
115 DALI_LOG_ERROR("DBusClient connection is not ready\n");
119 connectionState->object = DBUS_W->eldbus_object_get_impl(connectionState->connection, busName.c_str(), pathName.c_str());
120 if(connectionState->object)
122 connectionState->proxy = DBUS_W->eldbus_proxy_get_impl(connectionState->object, interfaceName);
123 if(interfaceName != DBUS_INTERFACE_PROPERTIES)
125 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_get_impl(connectionState->object, DBUS_INTERFACE_PROPERTIES);
129 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_copy_impl(connectionState->proxy);
132 connectionInfo = std::make_shared<ConnectionInfo>();
133 connectionInfo->busName = std::move(busName);
134 connectionInfo->pathName = std::move(pathName);
135 connectionInfo->interfaceName = std::move(interfaceName);
138 DBus::DBusServer::DBusServer(ConnectionType tp)
139 : DBus::DBusServer(DBus::getDBusConnectionByType(tp))
143 DBus::DBusServer::DBusServer(const DBusWrapper::ConnectionPtr& conn)
146 connection = getDBusConnectionByType(ConnectionType::SESSION);
151 DBus::DBusInterfaceDescription::DBusInterfaceDescription(std::string interfaceName)
152 : interfaceName(std::move(interfaceName))
156 void DBus::DBusServer::addInterface(const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback)
158 DBUS_W->add_interface_impl(fallback, pathName, connection, destructorObject->destructors, dscr.interfaceName, dscr.methods, dscr.properties, dscr.signals);
161 std::string DBus::DBusServer::getBusName() const
163 return getConnectionName(connection);
166 std::string DBus::getConnectionName(const DBusWrapper::ConnectionPtr& c)
168 return DBUS_W->eldbus_connection_unique_name_get_impl(c);
171 void DBus::requestBusName(const DBusWrapper::ConnectionPtr& conn, const std::string& bus)
173 DBUS_W->eldbus_name_request_impl(conn, bus);
176 void DBus::releaseBusName(const DBusWrapper::ConnectionPtr& conn, const std::string& bus)
178 DBUS_W->eldbus_name_release_impl(conn, bus);
181 bool DBus::DBusClient::getFromEinaValue(const _Eina_Value* v, void* dst)
183 return eina_value_get(const_cast<Eina_Value*>(v), dst);
186 static std::unique_ptr<DBusWrapper> InstalledWrapper;
188 struct DefaultDBusWrapper : public DBusWrapper
190 constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
196 ~DefaultDBusWrapper()
200 #define DEFINE_GS(name, eldbus_name, unref_call) \
201 static eldbus_name* get(const std::shared_ptr<name>& a) \
203 return static_cast<name##Impl*>(a.get())->Value; \
205 static eldbus_name* release(const std::shared_ptr<name>& a) \
207 auto z = static_cast<name##Impl*>(a.get())->Value; \
208 static_cast<name##Impl*>(a.get())->Value = nullptr; \
211 template<typename... ARGS> \
212 static std::shared_ptr<name> create(const eldbus_name* v, ARGS&&... args) \
214 return std::make_shared<name##Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
217 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
218 struct name##Impl : public name \
220 eldbus_name* Value = nullptr; \
221 bool EraseOnExit = false; \
222 name##Impl(eldbus_name* Value, bool EraseOnExit = false): Value(Value), \
223 EraseOnExit(EraseOnExit) \
228 if(EraseOnExit && Value) \
234 DEFINE_GS(name, eldbus_name, unref_call)
236 struct ConnectionImpl : public Connection
238 Eldbus_Connection* Value = nullptr;
239 bool EraseOnExit = false;
240 ConnectionImpl(Eldbus_Connection* Value, bool EraseOnExit = false)
242 EraseOnExit(EraseOnExit)
250 if(EraseOnExit && Value)
252 eldbus_connection_unref(Value);
255 ecore_event_shutdown();
259 struct MessageIterImpl : public MessageIter
261 Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
262 bool EraseOnExit = false;
263 MessageIterImpl(Eldbus_Message_Iter* Value, Eldbus_Message_Iter* Parent, bool EraseOnExit = false)
266 EraseOnExit(EraseOnExit)
272 if(EraseOnExit && Value && Parent)
274 eldbus_message_iter_container_close(Parent, Value);
279 DEFINE_GS(Connection, Eldbus_Connection, )
280 DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
281 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref(Value))
282 DEFINE_TYPE(Proxy, Eldbus_Proxy, )
283 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref(Value))
284 DEFINE_TYPE(Pending, Eldbus_Pending, )
285 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
288 std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string& addr) override
291 auto p = eldbus_address_connection_get(addr.c_str());
292 auto w = create(p, true);
297 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
298 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, type src) override \
300 eldbus_message_iter_arguments_append(get(it), #sig, src); \
302 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, type& dst) override \
304 return eldbus_message_iter_get_and_next(get(it), (#sig)[0], &dst); \
308 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
309 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
310 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
311 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
312 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
313 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
314 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
315 eldbus_message_iter_arguments_append_impl_basic(double, d)
318 #undef eldbus_message_iter_arguments_append_impl_basic
320 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, bool src) override
322 eldbus_message_iter_arguments_append(get(it), "b", src ? 1 : 0);
325 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, bool& dst) override
328 auto z = eldbus_message_iter_get_and_next(get(it), 'b', &q);
333 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const std::string& src) override
335 eldbus_message_iter_arguments_append(get(it), "s", src.c_str());
338 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, std::string& dst) override
342 if(!eldbus_message_iter_get_and_next(iter, 's', &q))
344 if(!eldbus_message_iter_get_and_next(iter, 'o', &q))
353 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr& it, const ObjectPath& src) override
355 eldbus_message_iter_arguments_append(get(it), "o", src.value.c_str());
358 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr& it, ObjectPath& dst) override
361 if(!eldbus_message_iter_get_and_next(get(it), 'o', &q))
369 MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr& it, int type, const std::string& sig) override
371 auto z = eldbus_message_iter_container_new(get(it), type, !sig.empty() ? sig.c_str() : NULL);
372 return create(z, get(it), true);
375 MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr& it, int type) override
377 Eldbus_Message_Iter* entry;
378 if(!eldbus_message_iter_get_and_next(get(it), type, &entry))
382 return create(entry, get(it), false);
385 MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr& msg, bool) override
387 return create(eldbus_message_iter_get(get(msg)), nullptr, false);
390 MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr& proxy, const std::string& funcName)
392 return create(eldbus_proxy_method_call_new(get(proxy), funcName.c_str()));
395 MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr& proxy, const MessagePtr& msg) override
397 return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT));
400 bool eldbus_message_error_get_impl(const MessagePtr& msg, std::string& name, std::string& text) override
402 const char *errname, *errmsg;
403 if(eldbus_message_error_get(get(msg), &errname, &errmsg))
412 std::string eldbus_message_signature_get_impl(const MessagePtr& msg) override
414 return eldbus_message_signature_get(get(msg));
417 static void callAsyncCb(void* data, const Eldbus_Message* msg, Eldbus_Pending* pending)
419 auto d = static_cast<SendCallback*>(data);
420 (*d)(create(msg, false));
423 static void pendingFreeCb(void* data, const void*)
425 auto d = static_cast<SendCallback*>(data);
429 static void listenerCallbackFree(void* data, const void*)
431 auto d = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
435 PendingPtr eldbus_proxy_send_impl(const ProxyPtr& proxy, const MessagePtr& msg, const SendCallback& callback) override
437 auto cb = new SendCallback{callback};
438 auto pending = eldbus_proxy_send(get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT);
441 eldbus_pending_free_cb_add(pending, pendingFreeCb, cb);
447 return create(pending, false);
450 std::string eldbus_proxy_interface_get_impl(const ProxyPtr& proxy) override
452 return eldbus_proxy_interface_get(get(proxy));
455 static void listenerCallback(void* data, const Eldbus_Message* msg)
457 auto p = static_cast<std::function<void(const Eldbus_Message* msg)>*>(data);
461 void eldbus_proxy_signal_handler_add_impl(const ProxyPtr& proxy, const std::string& member, const std::function<void(const MessagePtr&)>& cb) override
463 auto tmp = new std::function<void(const Eldbus_Message* msg)>{
464 [cb](const Eldbus_Message* msg) {
465 cb(create(msg, false));
467 auto handler = eldbus_proxy_signal_handler_add(get(proxy), member.c_str(), listenerCallback, tmp);
470 eldbus_proxy_free_cb_add(get(proxy), listenerCallbackFree, tmp);
478 std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr& iter) override
480 return eldbus_message_iter_signature_get(get(iter));
483 MessagePtr eldbus_message_method_return_new_impl(const MessagePtr& msg) override
485 return create(eldbus_message_method_return_new(get(msg)));
488 MessagePtr eldbus_message_error_new_impl(const MessagePtr& msg, const std::string& err, const std::string& txt) override
490 return create(eldbus_message_error_new(get(msg), err.c_str(), txt.c_str()));
493 PendingPtr eldbus_connection_send_impl(const ConnectionPtr& conn, const MessagePtr& msg) override
495 return create(eldbus_connection_send(get(conn), get(msg), NULL, NULL, -1));
498 MessagePtr eldbus_message_signal_new_impl(const std::string& path, const std::string& iface, const std::string& name) override
500 return create(eldbus_message_signal_new(path.c_str(), iface.c_str(), name.c_str()));
503 MessagePtr eldbus_message_ref_impl(const MessagePtr& msg) override
505 return create(eldbus_message_ref(get(msg)), true);
508 ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override
510 Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
514 case ConnectionType::SYSTEM:
516 eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
519 case ConnectionType::SESSION:
521 eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
526 auto p = eldbus_connection_get(eldbusType);
529 DALI_LOG_ERROR("cannot get dbus connection\n");
532 auto w = create(p, true);
536 std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr& conn) override
538 return eldbus_connection_unique_name_get(get(conn));
541 ObjectPtr eldbus_object_get_impl(const ConnectionPtr& conn, const std::string& bus, const std::string& path) override
543 return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str()), true);
546 ProxyPtr eldbus_proxy_get_impl(const ObjectPtr& obj, const std::string& interface) override
548 return create(eldbus_proxy_get(get(obj), interface.c_str()), false);
551 ProxyPtr eldbus_proxy_copy_impl(const ProxyPtr& ptr) override
553 return create(get(ptr), false);
556 void eldbus_name_request_impl(const ConnectionPtr& conn, const std::string& bus) override
558 eldbus_name_request(get(conn), bus.c_str(), ELDBUS_NAME_REQUEST_FLAG_DO_NOT_QUEUE, nullptr, nullptr);
561 void eldbus_name_release_impl(const ConnectionPtr& conn, const std::string& bus) override
563 eldbus_name_release(get(conn), bus.c_str(), nullptr, nullptr);
566 struct Implementation
568 Eldbus_Service_Interface_Desc dsc;
569 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
570 std::vector<Eldbus_Method> methods;
571 std::vector<Eldbus_Signal> signals;
572 std::vector<Eldbus_Property> properties;
574 std::unordered_map<std::string, DBusWrapper::MethodInfo> methodsMap;
575 std::unordered_map<std::string, DBusWrapper::PropertyInfo> propertiesMap;
576 std::unordered_map<unsigned int, DBusWrapper::SignalInfo> signalsMap;
578 DBusWrapper::ConnectionWeakPtr connection;
583 static GlobalEntries& Get()
585 static GlobalEntries instance;
589 Implementation* Find(const Eldbus_Service_Interface* iface)
591 Implementation* impl = nullptr;
592 std::lock_guard<std::mutex> lock(globalEntriesMutex);
593 auto it = globalEntries.find(iface);
594 if(it != globalEntries.end())
596 impl = it->second.get();
601 void Add(const Eldbus_Service_Interface* iface, std::unique_ptr<Implementation> impl)
603 std::lock_guard<std::mutex> lock(globalEntriesMutex);
604 globalEntries[iface] = std::move(impl);
607 void Erase(const Eldbus_Service_Interface* iface)
609 std::lock_guard<std::mutex> lock(globalEntriesMutex);
610 globalEntries.erase(iface);
614 std::unordered_map<const Eldbus_Service_Interface*, std::unique_ptr<Implementation>> globalEntries;
615 std::mutex globalEntriesMutex;
620 #define EINA_FALSE static_cast<Eina_Bool>(0)
621 #define EINA_TRUE static_cast<Eina_Bool>(1)
623 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)
625 Implementation* impl = GlobalEntries::Get().Find(iface);
631 auto it = impl->propertiesMap.find(propertyName);
632 if(it == impl->propertiesMap.end() || !it->second.getCallback)
637 auto connection = impl->connection.lock();
643 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
644 auto reply = it->second.getCallback(create(message, false), create(iter, nullptr, false));
649 *error = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
657 static Eldbus_Message* property_set_callback(const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter, const Eldbus_Message* message)
659 Implementation* impl = GlobalEntries::Get().Find(iface);
662 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
665 auto it = impl->propertiesMap.find(propertyName);
666 if(it == impl->propertiesMap.end() || !it->second.setCallback)
668 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown setter");
671 auto connection = impl->connection.lock();
674 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
678 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
679 auto reply = it->second.setCallback(create(message, false), create(iter, nullptr, false));
681 Eldbus_Message* ret = nullptr;
684 ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", reply.c_str());
688 ret = eldbus_message_method_return_new(message);
693 static Eldbus_Message* method_callback(const Eldbus_Service_Interface* iface, const Eldbus_Message* message)
695 Implementation* impl = GlobalEntries::Get().Find(iface);
698 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown interface");
701 std::string memberName = eldbus_message_member_get(message);
702 auto it = impl->methodsMap.find(memberName);
703 if(it == impl->methodsMap.end())
705 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Unknown method");
708 auto connection = impl->connection.lock();
711 auto ret = eldbus_message_error_new(message, "org.freedesktop.DBus.Error.Failed", "Connection lost");
714 DBus::DBusServer::CurrentObjectSetter currentObjectSetter(connection, eldbus_message_path_get(message));
715 auto reply = it->second.callback(create(message));
716 return release(reply);
719 void add_interface_impl(bool fallback,
720 const std::string& pathName,
721 const ConnectionPtr& connection,
722 std::vector<std::function<void()>>& destructors,
723 const std::string& interfaceName,
724 std::vector<MethodInfo>& dscrMethods,
725 std::vector<PropertyInfo>& dscrProperties,
726 std::vector<SignalInfo>& dscrSignals) override
728 std::vector<Eldbus_Method> methods;
729 std::vector<Eldbus_Signal> signals;
730 std::vector<Eldbus_Property> properties;
731 std::vector<std::vector<Eldbus_Arg_Info>> argsInfos;
732 std::unordered_map<std::string, DBus::DBusInterfaceDescription::MethodInfo> methodsMap;
733 std::unordered_map<std::string, DBus::DBusInterfaceDescription::PropertyInfo> propertiesMap;
734 std::unordered_map<unsigned int, DBus::DBusInterfaceDescription::SignalInfo> signalsMap;
736 DBUS_DEBUG("interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName(connection).c_str());
737 auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>>& input) {
738 argsInfos.push_back({});
739 auto& dst = argsInfos.back();
742 auto a = Strings.add(s.first);
743 auto b = Strings.add(s.second);
744 dst.push_back({a, b});
746 dst.push_back({nullptr, nullptr});
749 for(auto& ee : dscrMethods)
751 auto key = ee.memberName;
752 DBUS_DEBUG("adding method %s", ee.memberName.c_str());
755 DBUS_DEBUG("in %s '%s'", r.first.c_str(), r.second.c_str());
757 for(auto& r : ee.out)
759 DBUS_DEBUG("out %s '%s'", r.first.c_str(), r.second.c_str());
761 auto& e = (methodsMap[key] = std::move(ee));
762 methods.push_back({});
763 auto& m = methods.back();
764 m.member = e.memberName.c_str();
765 m.in = makeArgInfo(e.in);
766 m.out = makeArgInfo(e.out);
767 m.cb = method_callback;
770 for(auto& ee : dscrProperties)
772 auto key = ee.memberName;
773 DBUS_DEBUG("adding property %s", ee.memberName.c_str());
774 auto& e = (propertiesMap[key] = std::move(ee));
775 properties.push_back({});
776 auto& m = properties.back();
777 m.name = e.memberName.c_str();
778 m.type = e.typeSignature.c_str();
779 m.get_func = e.getCallback ? property_get_callback : nullptr;
780 m.set_func = e.setCallback ? property_set_callback : nullptr;
784 dscrProperties.clear();
787 methods.push_back({nullptr, nullptr, nullptr, nullptr, 0});
788 signals.push_back({nullptr, nullptr, 0});
789 properties.push_back({nullptr, nullptr, nullptr, nullptr, 0});
791 auto impl = std::unique_ptr<Implementation>(new Implementation{
792 {interfaceName.c_str(),
798 std::move(argsInfos),
801 std::move(properties),
802 std::move(methodsMap),
803 std::move(propertiesMap),
804 std::move(signalsMap),
807 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);
808 DALI_ASSERT_ALWAYS(v && "Eldbus register failed!");
809 GlobalEntries::Get().Add(v, std::move(impl));
810 DBUS_DEBUG("registering interface %p (%d)", v, fallback ? 1 : 0);
811 destructors.push_back([=]() {
812 DBUS_DEBUG("unregistering interface %p", v);
813 GlobalEntries::Get().Erase(v);
814 eldbus_service_interface_unregister(v);
818 static void listenerEventChangedCallback(void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event)
820 auto p = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
821 (*p)(static_cast<Eldbus_Proxy_Event_Property_Changed*>(event));
824 static void ProxyEventCallbackDelCb(void* data, const void* obj)
826 auto d = static_cast<std::function<void(Eldbus_Proxy_Event_Property_Changed*)>*>(data);
830 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
832 auto callbackLambdaPtr = new std::function<void(Eldbus_Proxy_Event_Property_Changed * epc)>{
833 [cb, name, interface](Eldbus_Proxy_Event_Property_Changed* ev) {
834 const char* ifc = eldbus_proxy_interface_get(ev->proxy);
835 if(ev->name && ev->name == name && ifc && interface == ifc)
841 eldbus_proxy_event_callback_add(p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, listenerEventChangedCallback, callbackLambdaPtr);
842 eldbus_proxy_free_cb_add(p, ProxyEventCallbackDelCb, callbackLambdaPtr);
846 DBusWrapper* DBusWrapper::Installed()
848 if(!InstalledWrapper)
850 InstalledWrapper.reset(new DefaultDBusWrapper);
852 return InstalledWrapper.get();
855 void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
857 InstalledWrapper = std::move(w);