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/tizen-wayland/atspi/dbus.h>
19 #include <dali/internal/accessibility/tizen-wayland/atspi/accessibility-common.h>
27 #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 ) : DBusClient( std::move( busName ), std::move( pathName ), std::move( interfaceName ), getDBusConnectionByType( tp ) )
105 DBus::DBusClient::DBusClient( std::string busName, std::string pathName, std::string interfaceName, const DBusWrapper::ConnectionPtr &conn )
108 connectionState->connection = getDBusConnectionByType( ConnectionType::SESSION );
110 connectionState->connection = conn;
112 std::ostringstream o;
113 o << "bus = " << busName << " path = " << pathName << " connection = " << DBUS_W->eldbus_connection_unique_name_get_impl( connectionState->connection );
116 connectionState->object = DBUS_W->eldbus_object_get_impl( connectionState->connection, busName.c_str(), pathName.c_str() );
117 if( connectionState->object )
119 connectionState->proxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, interfaceName );
120 if( interfaceName != DBUS_INTERFACE_PROPERTIES )
122 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_get_impl( connectionState->object, DBUS_INTERFACE_PROPERTIES );
126 connectionState->propertiesProxy = DBUS_W->eldbus_proxy_copy_impl( connectionState->proxy );
129 connectionInfo = std::make_shared< ConnectionInfo >();
130 connectionInfo->busName = std::move( busName );
131 connectionInfo->pathName = std::move( pathName );
132 connectionInfo->interfaceName = std::move( interfaceName );
135 DBus::DBusServer::DBusServer( ConnectionType tp ) : DBus::DBusServer( DBus::getDBusConnectionByType( tp ) )
139 DBus::DBusServer::DBusServer( const DBusWrapper::ConnectionPtr &conn )
142 connection = getDBusConnectionByType( ConnectionType::SESSION );
147 DBus::DBusInterfaceDescription::DBusInterfaceDescription( std::string interfaceName ) : interfaceName( std::move( interfaceName ) )
151 void DBus::DBusServer::addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback )
153 DBUS_W->add_interface_impl( fallback, pathName, connection, destructorObject->destructors, dscr.interfaceName, dscr.methods, dscr.properties, dscr.signals );
156 std::string DBus::DBusServer::getBusName() const
158 return getConnectionName( connection );
161 std::string DBus::getConnectionName( const DBusWrapper::ConnectionPtr &c )
163 return DBUS_W->eldbus_connection_unique_name_get_impl( c );
166 bool DBus::DBusClient::getFromEinaValue(const _Eina_Value *v, void *dst)
168 return eina_value_get(const_cast<Eina_Value*>(v), dst);
171 static std::unique_ptr<DBusWrapper> InstalledWrapper;
173 struct DefaultDBusWrapper : public DBusWrapper
175 constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
181 ~DefaultDBusWrapper()
185 #define DEFINE_GS(name, eldbus_name, unref_call) \
186 static eldbus_name *get(const std::shared_ptr<name> &a) { \
187 return static_cast<name ## Impl*>(a.get())->Value; \
189 static eldbus_name *release(const std::shared_ptr<name> &a) { \
190 auto z = static_cast<name ## Impl*>(a.get())->Value; \
191 static_cast<name ## Impl*>(a.get())->Value = nullptr; \
194 template <typename ... ARGS> static std::shared_ptr<name> create(const eldbus_name *v, ARGS && ... args) { \
195 return std::make_shared<name ## Impl>(const_cast<eldbus_name*>(v), std::forward<ARGS>(args)...); \
198 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
199 struct name ## Impl : public name { \
200 eldbus_name *Value = nullptr; \
201 bool EraseOnExit = false; \
202 name ## Impl(eldbus_name *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit) { } \
204 if (EraseOnExit && Value) { unref_call; } \
207 DEFINE_GS(name, eldbus_name, unref_call)
209 struct ConnectionImpl : public Connection
211 Eldbus_Connection *Value = nullptr;
212 bool EraseOnExit = false;
213 ConnectionImpl(Eldbus_Connection *Value, bool EraseOnExit = false) : Value(Value), EraseOnExit(EraseOnExit)
221 if (EraseOnExit && Value)
223 eldbus_connection_unref( Value );
226 ecore_event_shutdown();
230 struct MessageIterImpl : public MessageIter
232 Eldbus_Message_Iter *Value = nullptr, *Parent = nullptr;
233 bool EraseOnExit = false;
234 MessageIterImpl(Eldbus_Message_Iter *Value, Eldbus_Message_Iter *Parent, bool EraseOnExit = false) : Value(Value), Parent(Parent), EraseOnExit(EraseOnExit)
240 if (EraseOnExit && Value && Parent)
242 eldbus_message_iter_container_close(Parent, Value);
247 DEFINE_GS(Connection, Eldbus_Connection, )
248 DEFINE_GS(MessageIter, Eldbus_Message_Iter, )
249 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref( Value ))
250 DEFINE_TYPE(Proxy, Eldbus_Proxy, )
251 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref( Value ))
252 DEFINE_TYPE(Pending, Eldbus_Pending, )
253 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
256 std::shared_ptr<Connection> eldbus_address_connection_get_impl(const std::string &addr) override
259 auto p = eldbus_address_connection_get(addr.c_str());
260 auto w = create(p, true);
265 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
266 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type src) override { \
267 eldbus_message_iter_arguments_append( get(it), #sig, src ); \
269 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type &dst) override { \
270 return eldbus_message_iter_get_and_next( get(it), (#sig)[0], &dst ); \
273 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
274 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
275 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
276 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
277 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
278 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
279 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
280 eldbus_message_iter_arguments_append_impl_basic(double, d)
282 #undef eldbus_message_iter_arguments_append_impl_basic
284 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, bool src) override
286 eldbus_message_iter_arguments_append( get(it), "b", src ? 1 : 0 );
289 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, bool &dst) override
292 auto z = eldbus_message_iter_get_and_next( get(it), 'b', &q );
297 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const std::string &src) override
299 eldbus_message_iter_arguments_append( get(it), "s", src.c_str() );
302 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, std::string &dst) override
306 if( !eldbus_message_iter_get_and_next( iter, 's', &q ) )
308 if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
317 void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, const ObjectPath &src) override
319 eldbus_message_iter_arguments_append( get(it), "o", src.value.c_str() );
322 bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, ObjectPath &dst) override
325 if( !eldbus_message_iter_get_and_next( get(it), 'o', &q ) )
333 MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr &it, int type, const std::string &sig) override
335 auto z = eldbus_message_iter_container_new( get(it), type, !sig.empty() ? sig.c_str() : NULL );
336 return create(z, get(it), true);
339 MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr &it, int type) override
341 Eldbus_Message_Iter* entry;
342 if (!eldbus_message_iter_get_and_next( get(it), type, &entry ) )
346 return create(entry, get(it), false);
349 MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr &msg, bool) override
351 return create(eldbus_message_iter_get(get(msg)), nullptr, false);
354 MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr &proxy, const std::string &funcName)
356 return create(eldbus_proxy_method_call_new( get(proxy), funcName.c_str() ) );
359 MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr &proxy, const MessagePtr &msg) override
361 return create(eldbus_proxy_send_and_block(get(proxy), release(msg), ELDBUS_CALL_TIMEOUT) );
364 bool eldbus_message_error_get_impl(const MessagePtr &msg, std::string &name, std::string &text) override
366 const char *errname, *errmsg;
367 if( eldbus_message_error_get( get(msg), &errname, &errmsg ) )
376 std::string eldbus_message_signature_get_impl(const MessagePtr &msg) override
378 return eldbus_message_signature_get(get(msg));
381 static void callAsyncCb( void* data, const Eldbus_Message *msg, Eldbus_Pending *pending )
383 auto d = static_cast< SendCallback* >( data );
384 (*d)( create(msg, false) );
387 static void pendingFreeCb( void* data, const void* )
389 auto d = static_cast< SendCallback* >( data );
393 static void listenerCallbackFree( void* data, const void* )
395 auto d = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
399 PendingPtr eldbus_proxy_send_impl(const ProxyPtr &proxy, const MessagePtr &msg, const SendCallback &callback) override
401 auto cb = new SendCallback{ callback };
402 auto pending = eldbus_proxy_send( get(proxy), release(msg), callAsyncCb, cb, ELDBUS_CALL_TIMEOUT );
405 eldbus_pending_free_cb_add( pending, pendingFreeCb, cb );
411 return create(pending, false);
414 std::string eldbus_proxy_interface_get_impl(const ProxyPtr &proxy) override
416 return eldbus_proxy_interface_get( get(proxy) );
419 static void listenerCallback( void* data, const Eldbus_Message* msg )
421 auto p = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
425 void eldbus_proxy_signal_handler_add_impl(const ProxyPtr &proxy, const std::string &member, const std::function<void(const MessagePtr &)> &cb) override
427 auto tmp = new std::function< void( const Eldbus_Message* msg ) >
429 [cb](const Eldbus_Message* msg)
431 cb(create(msg, false));
434 auto handler = eldbus_proxy_signal_handler_add( get(proxy), member.c_str(), listenerCallback, tmp );
437 eldbus_proxy_free_cb_add( get(proxy), listenerCallbackFree, tmp );
445 std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr &iter) override
447 return eldbus_message_iter_signature_get( get(iter) );
450 MessagePtr eldbus_message_method_return_new_impl( const MessagePtr &msg) override
452 return create(eldbus_message_method_return_new( get(msg) ) );
455 MessagePtr eldbus_message_error_new_impl( const MessagePtr &msg, const std::string &err, const std::string &txt ) override
457 return create(eldbus_message_error_new( get(msg), err.c_str(), txt.c_str() ) );
460 PendingPtr eldbus_connection_send_impl(const ConnectionPtr &conn, const MessagePtr &msg) override
462 return create(eldbus_connection_send( get(conn), get(msg), NULL, NULL, -1 ) );
465 MessagePtr eldbus_message_signal_new_impl(const std::string &path, const std::string &iface, const std::string &name) override
467 return create(eldbus_message_signal_new( path.c_str(), iface.c_str(), name.c_str() ) );
470 MessagePtr eldbus_message_ref_impl(const MessagePtr &msg) override
472 return create(eldbus_message_ref( get(msg) ), true );
475 ConnectionPtr eldbus_connection_get_impl(ConnectionType type) override
477 Eldbus_Connection_Type eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
481 case ConnectionType::SYSTEM:
483 eldbusType = ELDBUS_CONNECTION_TYPE_SYSTEM;
486 case ConnectionType::SESSION:
488 eldbusType = ELDBUS_CONNECTION_TYPE_SESSION;
494 auto p = eldbus_connection_get( eldbusType );
495 auto w = create(p, true);
500 std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr &conn) override
502 return eldbus_connection_unique_name_get( get(conn) );
505 ObjectPtr eldbus_object_get_impl( const ConnectionPtr &conn, const std::string &bus, const std::string &path ) override
507 return create(eldbus_object_get(get(conn), bus.c_str(), path.c_str() ), true );
510 ProxyPtr eldbus_proxy_get_impl( const ObjectPtr &obj, const std::string &interface ) override
512 return create(eldbus_proxy_get(get(obj), interface.c_str() ), false );
515 ProxyPtr eldbus_proxy_copy_impl( const ProxyPtr &ptr) override
517 return create(get(ptr), false );
520 struct Implementation
522 Eldbus_Service_Interface_Desc dsc;
523 std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
524 std::vector< Eldbus_Method > methods;
525 std::vector< Eldbus_Signal > signals;
526 std::vector< Eldbus_Property > properties;
528 std::unordered_map< std::string, DBusWrapper::MethodInfo > methodsMap;
529 std::unordered_map< std::string, DBusWrapper::PropertyInfo > propertiesMap;
530 std::unordered_map< unsigned int, DBusWrapper::SignalInfo > signalsMap;
532 DBusWrapper::ConnectionWeakPtr connection;
535 static std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< Implementation > > globalEntries;
536 static std::mutex globalEntriesMutex;
540 #define EINA_FALSE static_cast<Eina_Bool>(0)
541 #define EINA_TRUE static_cast<Eina_Bool>(1)
543 static Eina_Bool property_get_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
544 const Eldbus_Message* message, Eldbus_Message** error )
546 Implementation* impl = nullptr;
548 std::lock_guard< std::mutex > lock( globalEntriesMutex );
549 auto it = globalEntries.find( iface );
550 if( it != globalEntries.end() )
552 impl = it->second.get();
560 auto it = impl->propertiesMap.find( propertyName );
561 if( it == impl->propertiesMap.end() || !it->second.getCallback )
566 auto connection = impl->connection.lock();
572 DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
573 auto reply = it->second.getCallback( create(message, false), create(iter, nullptr, false) );
578 *error = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
586 static Eldbus_Message* property_set_callback( const Eldbus_Service_Interface* iface, const char* propertyName, Eldbus_Message_Iter* iter,
587 const Eldbus_Message* message )
589 Implementation* impl = nullptr;
591 std::lock_guard< std::mutex > lock( globalEntriesMutex );
592 auto it = globalEntries.find( iface );
593 if( it != globalEntries.end() )
595 impl = it->second.get();
600 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
603 auto it = impl->propertiesMap.find( propertyName );
604 if( it == impl->propertiesMap.end() || !it->second.setCallback )
606 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown setter" );
609 auto connection = impl->connection.lock();
612 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
616 DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
617 auto reply = it->second.setCallback( create(message, false), create(iter, nullptr, false) );
619 Eldbus_Message* ret = nullptr;
622 ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", reply.c_str() );
626 ret = eldbus_message_method_return_new( message );
631 static Eldbus_Message* method_callback( const Eldbus_Service_Interface* iface, const Eldbus_Message* message )
633 Implementation* impl = nullptr;
635 std::lock_guard< std::mutex > lock( globalEntriesMutex );
636 auto it = globalEntries.find( iface );
637 if( it != globalEntries.end() )
638 impl = it->second.get();
642 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown interface" );
645 std::string memberName = eldbus_message_member_get( message );
646 auto it = impl->methodsMap.find( memberName );
647 if( it == impl->methodsMap.end() )
649 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Unknown method" );
652 auto connection = impl->connection.lock();
655 auto ret = eldbus_message_error_new( message, "org.freedesktop.DBus.Error.Failed", "Connection lost" );
658 DBus::DBusServer::CurrentObjectSetter currentObjectSetter( connection, eldbus_message_path_get( message ) );
659 auto reply = it->second.callback( create(message) );
660 return release(reply);
663 void add_interface_impl( bool fallback, const std::string& pathName,
664 const ConnectionPtr &connection,
665 std::vector<std::function<void()>> &destructors,
666 const std::string& interfaceName,
667 std::vector< MethodInfo >& dscrMethods,
668 std::vector< PropertyInfo >& dscrProperties,
669 std::vector< SignalInfo >& dscrSignals ) override
671 std::vector< Eldbus_Method > methods;
672 std::vector< Eldbus_Signal > signals;
673 std::vector< Eldbus_Property > properties;
674 std::vector< std::vector< Eldbus_Arg_Info > > argsInfos;
675 std::unordered_map< std::string, DBus::DBusInterfaceDescription::MethodInfo > methodsMap;
676 std::unordered_map< std::string, DBus::DBusInterfaceDescription::PropertyInfo > propertiesMap;
677 std::unordered_map< unsigned int, DBus::DBusInterfaceDescription::SignalInfo > signalsMap;
679 DBUS_DEBUG( "interface %s path %s on bus %s", interfaceName.c_str(), pathName.c_str(), DBus::getConnectionName( connection ).c_str() );
680 auto makeArgInfo = [&](const std::vector<std::pair<std::string, std::string>> &input) {
681 argsInfos.push_back({});
682 auto &dst = argsInfos.back();
685 auto a = Strings.add(s.first);
686 auto b = Strings.add(s.second);
687 dst.push_back({ a, b });
689 dst.push_back({ nullptr, nullptr });
692 for( auto& ee : dscrMethods )
694 auto key = ee.memberName;
695 DBUS_DEBUG( "adding method %s", ee.memberName.c_str() );
696 for( auto& r : ee.in )
698 DBUS_DEBUG( "in %s '%s'", r.first.c_str(), r.second.c_str() );
700 for( auto& r : ee.out )
702 DBUS_DEBUG( "out %s '%s'", r.first.c_str(), r.second.c_str() );
704 auto& e = ( methodsMap[key] = std::move( ee ) );
705 methods.push_back( {} );
706 auto& m = methods.back();
707 m.member = e.memberName.c_str();
708 m.in = makeArgInfo(e.in);
709 m.out = makeArgInfo(e.out);
710 m.cb = method_callback;
713 for( auto& ee : dscrProperties )
715 auto key = ee.memberName;
716 DBUS_DEBUG( "adding property %s", ee.memberName.c_str() );
717 auto& e = ( propertiesMap[key] = std::move( ee ) );
718 properties.push_back( {} );
719 auto& m = properties.back();
720 m.name = e.memberName.c_str();
721 m.type = e.typeSignature.c_str();
722 m.get_func = e.getCallback ? property_get_callback : nullptr;
723 m.set_func = e.setCallback ? property_set_callback : nullptr;
727 dscrProperties.clear();
730 methods.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
731 signals.push_back( {nullptr, nullptr, 0} );
732 properties.push_back( {nullptr, nullptr, nullptr, nullptr, 0} );
734 auto impl = std::unique_ptr< Implementation >( new Implementation{
735 {interfaceName.c_str(),
741 std::move( argsInfos ),
742 std::move( methods ),
743 std::move( signals ),
744 std::move( properties ),
745 std::move( methodsMap ),
746 std::move( propertiesMap ),
747 std::move( signalsMap ),
751 std::lock_guard< std::mutex > lock( globalEntriesMutex );
752 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 );
754 globalEntries[v] = std::move( impl );
755 DBUS_DEBUG( "registering interface %p (%d)", v, fallback ? 1 : 0 );
756 destructors.push_back([=]()
758 DBUS_DEBUG( "unregistering interface %p", v );
759 eldbus_service_interface_unregister( v );
760 std::lock_guard< std::mutex > lock( globalEntriesMutex );
761 globalEntries.erase( v );
767 static void listenerEventChangedCallback( void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event )
769 auto p = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
770 ( *p )( static_cast< Eldbus_Proxy_Event_Property_Changed* >( event ) );
773 static void ProxyEventCallbackDelCb( void* data, const void *obj )
775 auto d = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
779 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
781 auto callbackLambdaPtr = new std::function< void( Eldbus_Proxy_Event_Property_Changed *epc ) >
783 [cb, name, interface]( Eldbus_Proxy_Event_Property_Changed *ev )
785 const char* ifc = eldbus_proxy_interface_get( ev->proxy );
786 if( ev->name && ev->name == name && ifc && interface == ifc )
793 eldbus_proxy_event_callback_add( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED, listenerEventChangedCallback, callbackLambdaPtr );
794 eldbus_proxy_free_cb_add( p, ProxyEventCallbackDelCb, callbackLambdaPtr );
798 std::unordered_map< const Eldbus_Service_Interface*, std::unique_ptr< DefaultDBusWrapper::Implementation > > DefaultDBusWrapper::globalEntries;
799 std::mutex DefaultDBusWrapper::globalEntriesMutex;
801 DBusWrapper *DBusWrapper::Installed()
803 if (!InstalledWrapper)
805 InstalledWrapper.reset(new DefaultDBusWrapper);
807 return InstalledWrapper.get();
810 void DBusWrapper::Install(std::unique_ptr<DBusWrapper> w)
812 InstalledWrapper = std::move(w);