diff --git a/src/lib/eldbus/eldbus_private_types.h b/src/lib/eldbus/eldbus_private_types.h index bc4765d769..8ebe682544 100644 --- a/src/lib/eldbus/eldbus_private_types.h +++ b/src/lib/eldbus/eldbus_private_types.h @@ -146,6 +146,8 @@ struct _Eldbus_Service_Object Eldbus_Service_Object *parent; Eina_Inlist *children; + Eina_Bool fallback :1; /* Fallback mechanism flag */ + //ObjectManager data Eldbus_Service_Interface *objmanager; Eina_List *iface_added; diff --git a/src/lib/eldbus/eldbus_service.c b/src/lib/eldbus/eldbus_service.c index bb300c0865..3149a58a2f 100644 --- a/src/lib/eldbus/eldbus_service.c +++ b/src/lib/eldbus/eldbus_service.c @@ -647,7 +647,7 @@ _eldbus_service_object_parent_find(Eldbus_Service_Object *obj) } static Eldbus_Service_Object * -_eldbus_service_object_add(Eldbus_Connection *conn, const char *path) +_eldbus_service_object_add(Eldbus_Connection *conn, const char *path, Eina_Bool fallback) { Eldbus_Service_Object *obj, *rootobj; Eina_Inlist *safe; @@ -656,8 +656,9 @@ _eldbus_service_object_add(Eldbus_Connection *conn, const char *path) obj = calloc(1, sizeof(Eldbus_Service_Object)); EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL); - if (!dbus_connection_register_object_path(conn->dbus_conn, path, &vtable, - obj)) + obj->fallback = fallback; + if ((fallback && !dbus_connection_register_fallback(conn->dbus_conn, path, &vtable, obj)) || + (!fallback && !dbus_connection_register_object_path(conn->dbus_conn, path, &vtable, obj))) { free(obj); return NULL; @@ -668,6 +669,8 @@ _eldbus_service_object_add(Eldbus_Connection *conn, const char *path) obj->interfaces = eina_hash_string_superfast_new(NULL); eldbus_connection_free_cb_add(conn, _on_connection_free, obj); + if (obj->fallback) return obj; + eina_hash_add(obj->interfaces, introspectable->name, introspectable); eina_hash_add(obj->interfaces, properties_iface->name, properties_iface); @@ -924,8 +927,8 @@ fail_signature: return NULL; } -EAPI Eldbus_Service_Interface * -eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc) +static Eldbus_Service_Interface * +_eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc, Eina_Bool fallback) { Eldbus_Service_Object *obj; Eldbus_Service_Interface *iface; @@ -950,7 +953,7 @@ eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, con return NULL; if (!obj) - obj = _eldbus_service_object_add(conn, path); + obj = _eldbus_service_object_add(conn, path, fallback); else obj->introspection_dirty = EINA_TRUE; EINA_SAFETY_ON_NULL_GOTO(obj, fail); @@ -982,6 +985,18 @@ fail: return NULL; } +EAPI Eldbus_Service_Interface * +eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc) +{ + return _eldbus_service_interface_register(conn, path, desc, EINA_FALSE); +} + +EAPI Eldbus_Service_Interface * +eldbus_service_interface_fallback_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc) +{ + return _eldbus_service_interface_register(conn, path, desc, EINA_TRUE); +} + static Eina_Bool _idler_propschanged(void *data) { @@ -1275,11 +1290,18 @@ _object_handler(DBusConnection *dbus_conn EINA_UNUSED, DBusMessage *msg, void *u const Eldbus_Method *method; Eldbus_Message *eldbus_msg, *reply; Eldbus_Connection *conn; + const char* fallback_path = NULL; obj = user_data; if (!obj) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; conn = obj->conn; + if (obj->fallback) + { + fallback_path = eina_stringshare_add(obj->path); + eina_stringshare_replace(&obj->path, dbus_message_get_path(msg)); + } + DBG("Connection@%p Got message:\n" " Type: %s\n" " Path: %s\n" @@ -1331,6 +1353,12 @@ _object_handler(DBusConnection *dbus_conn EINA_UNUSED, DBusMessage *msg, void *u eldbus_connection_unref(conn); eldbus_shutdown(); + if (obj->fallback) + { + eina_stringshare_replace(&obj->path, fallback_path); + eina_stringshare_del(fallback_path); + } + return DBUS_HANDLER_RESULT_HANDLED; } diff --git a/src/lib/eldbus/eldbus_service.h b/src/lib/eldbus/eldbus_service.h index 5fa839d395..e5915dc15c 100644 --- a/src/lib/eldbus/eldbus_service.h +++ b/src/lib/eldbus/eldbus_service.h @@ -108,6 +108,21 @@ typedef struct _Eldbus_Service_Interface_Desc */ EAPI Eldbus_Service_Interface *eldbus_service_interface_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc) EINA_ARG_NONNULL(1, 2, 3); +/** + * @brief Register a fallback interface handler for a given subsection of the object hierarchy. + * Note: Use eldbus_service_interface_unregister() to unregister a interface. + * @param conn where the interface should listen + * @param path a '/' delimited string of path elements + * @param desc description of interface + * @see eldbus_service_interface_unregister() + * + * @since 1.9 + * + * @return Interface + */ +EAPI Eldbus_Service_Interface * +eldbus_service_interface_fallback_register(Eldbus_Connection *conn, const char *path, const Eldbus_Service_Interface_Desc *desc) EINA_ARG_NONNULL(1, 2, 3); + /** * @brief Unregister a interface. * Note: This doesn't unregister the object path if interface count reaches 0.