Fix critical D-Bus and gadget integration issues

This commit fixes several critical bugs preventing the module from working:

1. Agent D-Bus Object Lifecycle Fix:
   - Keep manager_obj reference alive in IWD_Agent structure
   - Prevents async RegisterAgent call from being canceled
   - Fixes 'Canceled by user' error during agent registration
   - Object is now properly unreferenced during shutdown

2. Signal Handler Cleanup Fix:
   - Don't manually delete signal handlers after object unref
   - eldbus_object_unref() automatically cleans up handlers
   - Prevents 'Eina Magic Check Failed' error on module unload
   - Fixes double-free of signal handlers

3. Gadget Integration Fix:
   - Set gcc->o_base directly to attach icon to gadcon
   - Prevents shelf layout corruption when adding module
   - Proper Enlightenment gadcon integration

4. Agent Path Fix:
   - Use IWD_DAEMON_PATH ('/net/connman/iwd') for AgentManager
   - AgentManager interface is on daemon object, not root
   - Fixes 'No matching method found' error

These fixes resolve:
- Module load/unload crashes
- Shelf disorganization
- Agent registration failures
- D-Bus signal handler corruption

The module should now load cleanly, register the agent successfully,
and unload without errors.
This commit is contained in:
nemunaire 2025-12-28 21:51:41 +07:00
commit d76a77b5b3
6 changed files with 69 additions and 28 deletions

View file

@ -77,7 +77,6 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
/* Create icon */
o = edje_object_add(gcc->gadcon->evas);
inst->icon = o;
inst->gadget = o;
/* Load theme */
char theme_path[PATH_MAX];
@ -91,14 +90,17 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
evas_object_color_set(o, 100, 150, 200, 255);
}
evas_object_resize(o, 16, 16);
evas_object_show(o);
/* Add mouse event handler */
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
_gadget_mouse_down_cb, inst);
/* Set gadcon object */
/* Set the icon as the gadcon's visual object */
inst->gadget = o;
gcc->o_base = o;
/* Set size constraints */
e_gadcon_client_min_size_set(gcc, 16, 16);
e_gadcon_client_aspect_set(gcc, 16, 16);
e_gadcon_client_show(gcc);
@ -194,15 +196,17 @@ _gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas)
{
/* Fallback to simple colored box */
evas_object_color_set(o, 100, 150, 200, 255);
evas_object_resize(o, 16, 16);
}
}
else
{
/* Fallback if module not initialized yet */
evas_object_color_set(o, 100, 150, 200, 255);
evas_object_resize(o, 16, 16);
}
evas_object_resize(o, 16, 16);
evas_object_show(o);
return o;
}
@ -225,19 +229,36 @@ _gadget_mouse_down_cb(void *data, Evas *e EINA_UNUSED,
Instance *inst = data;
Evas_Event_Mouse_Down *ev = event_info;
if (!inst) return;
if (!inst)
{
e_util_dialog_show("Debug", "Instance is NULL!");
return;
}
if (ev->button == 1) /* Left click */
{
INF("Gadget clicked - popup=%p device=%p", inst->popup, inst->device);
if (inst->popup)
{
/* Close popup */
INF("Closing popup");
iwd_popup_del(inst);
}
else
{
/* Open popup */
INF("Opening popup");
iwd_popup_new(inst);
/* Debug: Check if popup was created */
if (!inst->popup)
{
ERR("Failed to create popup!");
e_util_dialog_show("IWD Debug",
"Popup creation failed.<br>"
"Check if iwd is running and wireless device exists.");
}
}
}
}

View file

@ -18,16 +18,31 @@ iwd_popup_new(Instance *inst)
IWD_Network *net;
Eina_List *l;
if (!inst) return;
if (inst->popup) return;
if (!inst)
{
ERR("iwd_popup_new: inst is NULL");
return;
}
DBG("Creating popup");
if (inst->popup)
{
DBG("Popup already exists");
return;
}
INF("Creating popup for instance %p", inst);
/* Create popup */
popup = e_gadcon_popup_new(inst->gcc, 0);
if (!popup) return;
if (!popup)
{
ERR("e_gadcon_popup_new failed!");
e_util_dialog_show("IWD Error", "Failed to create gadcon popup");
return;
}
inst->popup = (void *)popup;
INF("Popup created: %p", popup);
/* Create main box */
box = elm_box_add(e_comp->elm);

View file

@ -66,6 +66,12 @@ iwd_agent_init(void)
return EINA_FALSE;
}
/* Initialize fields */
iwd_agent->manager_obj = NULL;
iwd_agent->pending_network_path = NULL;
iwd_agent->pending_passphrase = NULL;
iwd_agent->pending_msg = NULL;
/* Register D-Bus service interface */
iwd_agent->iface = eldbus_service_interface_register(conn, IWD_AGENT_PATH, &agent_desc);
if (!iwd_agent->iface)
@ -76,11 +82,11 @@ iwd_agent_init(void)
return EINA_FALSE;
}
/* Register agent with iwd */
obj = eldbus_object_get(conn, IWD_SERVICE, IWD_MANAGER_PATH);
/* Register agent with iwd daemon (AgentManager is at /net/connman/iwd) */
obj = eldbus_object_get(conn, IWD_SERVICE, IWD_DAEMON_PATH);
if (!obj)
{
ERR("Failed to get iwd manager object");
ERR("Failed to get iwd daemon object");
eldbus_service_interface_unregister(iwd_agent->iface);
E_FREE(iwd_agent);
iwd_agent = NULL;
@ -98,11 +104,12 @@ iwd_agent_init(void)
return EINA_FALSE;
}
/* Store object reference to keep it alive during async call */
iwd_agent->manager_obj = obj;
eldbus_proxy_call(proxy, "RegisterAgent", _agent_register_cb, NULL, -1, "o", IWD_AGENT_PATH);
eldbus_object_unref(obj);
INF("Agent initialized");
INF("Agent initialization started");
return EINA_TRUE;
}
@ -119,6 +126,9 @@ iwd_agent_shutdown(void)
if (iwd_agent->iface)
eldbus_service_interface_unregister(iwd_agent->iface);
if (iwd_agent->manager_obj)
eldbus_object_unref(iwd_agent->manager_obj);
eina_stringshare_del(iwd_agent->pending_network_path);
eina_stringshare_del(iwd_agent->pending_passphrase);
@ -216,7 +226,7 @@ _agent_unregister(void)
conn = iwd_dbus_conn_get();
if (!conn) return;
obj = eldbus_object_get(conn, IWD_SERVICE, IWD_MANAGER_PATH);
obj = eldbus_object_get(conn, IWD_SERVICE, IWD_DAEMON_PATH);
if (!obj) return;
proxy = eldbus_proxy_get(obj, IWD_AGENT_MANAGER_INTERFACE);

View file

@ -10,6 +10,7 @@
typedef struct _IWD_Agent
{
Eldbus_Service_Interface *iface;
Eldbus_Object *manager_obj; /* Keep reference to prevent call cancellation */
const char *pending_network_path;
const char *pending_passphrase;
const Eldbus_Message *pending_msg; /* Stored message to reply to */

View file

@ -157,24 +157,17 @@ _iwd_dbus_disconnect(void)
DBG("Disconnecting from iwd daemon");
if (iwd_dbus->interfaces_added)
{
eldbus_signal_handler_del(iwd_dbus->interfaces_added);
iwd_dbus->interfaces_added = NULL;
}
if (iwd_dbus->interfaces_removed)
{
eldbus_signal_handler_del(iwd_dbus->interfaces_removed);
iwd_dbus->interfaces_removed = NULL;
}
/* Unref the object first - this will clean up associated signal handlers */
if (iwd_dbus->manager_obj)
{
eldbus_object_unref(iwd_dbus->manager_obj);
iwd_dbus->manager_obj = NULL;
}
/* Clear handler pointers (they're already freed by object unref) */
iwd_dbus->interfaces_added = NULL;
iwd_dbus->interfaces_removed = NULL;
iwd_dbus->connected = EINA_FALSE;
}

View file

@ -7,6 +7,7 @@
/* iwd D-Bus service and interfaces */
#define IWD_SERVICE "net.connman.iwd"
#define IWD_MANAGER_PATH "/"
#define IWD_DAEMON_PATH "/net/connman/iwd"
#define IWD_MANAGER_INTERFACE "net.connman.iwd.Manager"
#define IWD_ADAPTER_INTERFACE "net.connman.iwd.Adapter"
#define IWD_DEVICE_INTERFACE "net.connman.iwd.Device"