static void _setup_nfc_adapters(GTlmNfc *self) { GList* objects = g_dbus_object_manager_get_objects(self->neard_manager); GList* objects_iter = objects; while (objects_iter != NULL) { GList* interfaces = g_dbus_object_get_interfaces(objects_iter->data); GList* interfaces_iter = interfaces; while (interfaces_iter != NULL) { g_debug("Checking managed object %s, interface %s", g_dbus_object_get_object_path (objects_iter->data), g_dbus_proxy_get_interface_name (interfaces_iter->data)); if (g_strcmp0(g_dbus_proxy_get_interface_name (interfaces_iter->data), "org.neard.Adapter") == 0) { _setup_nfc_adapter(self, interfaces_iter->data); } g_object_unref(interfaces_iter->data); interfaces_iter = interfaces_iter->next; } g_list_free(interfaces); g_object_unref(objects_iter->data); objects_iter = objects_iter->next; } g_list_free(objects); }
void _on_interface_added(GDBusObjectManager *manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { GTlmNfc* self = GTLM_NFC(user_data); GDBusProxy* proxy = G_DBUS_PROXY(interface); g_debug("Object %s added interface %s", g_dbus_object_get_object_path (object), g_dbus_proxy_get_interface_name (proxy)); if (g_strcmp0(g_dbus_proxy_get_interface_name (proxy), "org.neard.Adapter") == 0) { _setup_nfc_adapter(self, proxy); return; } if (g_strcmp0(g_dbus_proxy_get_interface_name (proxy), "org.neard.Tag") == 0) { g_signal_emit(self, signals[SIG_TAG_FOUND], 0, g_dbus_object_get_object_path (object)); return; } if (g_strcmp0(g_dbus_proxy_get_interface_name (proxy), "org.neard.Record") == 0) { GVariant* type_v = g_dbus_proxy_get_cached_property(proxy, "Type"); if (type_v == NULL || !g_variant_is_of_type(type_v, G_VARIANT_TYPE_STRING)) { g_debug("Type property is absent on a record"); g_signal_emit(self, signals[SIG_NO_RECORD_FOUND], 0); return; } const gchar* type = g_variant_get_string(type_v, NULL); g_debug("Record has type %s", type); if (g_strcmp0(type, "MIME") != 0) { g_variant_unref(type_v); g_signal_emit(self, signals[SIG_NO_RECORD_FOUND], 0); return; } g_variant_unref(type_v); GVariant* mimetype_v = g_dbus_proxy_get_cached_property(proxy, "MIME"); if (mimetype_v == NULL || !g_variant_is_of_type(type_v, G_VARIANT_TYPE_STRING)) { g_debug("MIME property is absent on a record"); g_signal_emit(self, signals[SIG_NO_RECORD_FOUND], 0); return; } const gchar* mimetype = g_variant_get_string(mimetype_v, NULL); g_debug("Record has MIME type %s", mimetype); if (g_strcmp0(mimetype, "application/gtlm-nfc") != 0) { g_variant_unref(mimetype_v); g_signal_emit(self, signals[SIG_NO_RECORD_FOUND], 0); return; } g_variant_unref(mimetype_v); } }
static void on_interface_proxy_properties_changed (GDBusObjectManager *manager, GDBusObjectProxy *object_proxy, GDBusProxy *interface_proxy, GVariant *changed_properties, const gchar * const *invalidated_properties, gpointer user_data) { CockpitDBusJson1 *self = user_data; cleanup_unref_object JsonBuilder *builder = prepare_builder ("interface-properties-changed"); json_builder_begin_object (builder); json_builder_set_member_name (builder, "objpath"); json_builder_add_string_value (builder, g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy))); json_builder_set_member_name (builder, "iface_name"); json_builder_add_string_value (builder, g_dbus_proxy_get_interface_name (interface_proxy)); /* It's a bit of a waste to send all properties - would be cheaper to just * send @changed_properties and @invalidated_properties. But this is simpler. */ json_builder_set_member_name (builder, "iface"); json_builder_begin_object (builder); add_interface (builder, G_DBUS_INTERFACE (interface_proxy), changed_properties); json_builder_end_object (builder); json_builder_end_object (builder); write_builder (self, builder); }
void _on_interface_removed(GDBusObjectManager *manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { GTlmNfc* self = GTLM_NFC(user_data); GDBusProxy* proxy = G_DBUS_PROXY(interface); g_debug("Object %s removed interface %s", g_dbus_object_get_object_path (object), g_dbus_proxy_get_interface_name (proxy)); if (g_strcmp0(g_dbus_proxy_get_interface_name (proxy), "org.neard.Tag") == 0) { g_signal_emit(self, signals[SIG_TAG_LOST], 0, g_dbus_object_get_object_path (object)); GVariant* adapter_v = g_dbus_proxy_get_cached_property(proxy, "Adapter"); if (adapter_v == NULL || !g_variant_is_of_type(adapter_v, G_VARIANT_TYPE_OBJECT_PATH)) { g_debug("Adapter property is absent on a tag"); return; } const gchar* adapter_path = g_variant_get_string(adapter_v, NULL); g_debug("Tag belongs to adapter %s", adapter_path); GError* error = NULL; GDBusProxy* adapter = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, /* GDBusInterfaceInfo */ "org.neard", adapter_path, "org.neard.Adapter", NULL, /* GCancellable */ &error); if (adapter == NULL) { g_debug ("Error creating adapter proxy: %s", error->message); g_error_free(error); g_variant_unref(adapter_v); return; } // start polling on an adapter _setup_nfc_adapter(self, adapter); g_object_unref(adapter); g_variant_unref(adapter_v); return; } }
static void add_interface (JsonBuilder *builder, GDBusInterface *interface, GVariant *changed_properties) { gchar *s; json_builder_set_member_name (builder, g_dbus_proxy_get_interface_name (G_DBUS_PROXY (interface))); json_builder_begin_object (builder); if (changed_properties == NULL) { gchar **properties; guint n; properties = g_dbus_proxy_get_cached_property_names (G_DBUS_PROXY (interface)); for (n = 0; properties != NULL && properties[n] != NULL; n++) { const gchar *property_name = properties[n]; GVariant *value; value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (interface), property_name); if (value != NULL) { s = g_strconcat ("dbus_prop_", property_name, NULL); json_builder_set_member_name (builder, s); g_free (s); _json_builder_add_gvariant (builder, value); g_variant_unref (value); } } g_strfreev (properties); if (properties == NULL) { json_builder_set_member_name (builder, "HackEmpty"); json_builder_add_string_value (builder, "HackEmpty"); } } else { GVariantIter iter; const gchar *property_name; GVariant *value; g_variant_iter_init (&iter, changed_properties); while (g_variant_iter_next (&iter, "{&sv}", &property_name, &value)) { s = g_strconcat ("dbus_prop_", property_name, NULL); json_builder_set_member_name (builder, property_name); g_free (s); _json_builder_add_gvariant (builder, value); g_variant_unref (value); } } json_builder_end_object (builder); }
static void print_proxy_info (GDBusProxy *proxy) { g_print ("proxy info:\n" "name %s\n" "name owner %s\n" "object path %s\n" "interface name %s\n", g_dbus_proxy_get_name (proxy), g_dbus_proxy_get_name_owner (proxy), g_dbus_proxy_get_object_path (proxy), g_dbus_proxy_get_interface_name (proxy)); }
/* D-Bus has an upper limit on number of Match rules and it's rather easy * to hit as the proxy likes to add one for each object. Let's remove the Match * rule the proxy added and ensure a less granular rule is present instead. * * Also, don't do this immediately since it has a performance penalty. * Still better than loosing the signals altogether. * * Ideally, we should be able to tell glib not to hook its rules: * https://bugzilla.gnome.org/show_bug.cgi?id=758749 */ static void _nm_dbus_proxy_replace_match (GDBusProxy *proxy) { GDBusConnection *connection = g_dbus_proxy_get_connection (proxy); static unsigned match_counter = 1024; gchar *match; nm_assert (!g_strcmp0 (g_dbus_proxy_get_name (proxy), NM_DBUS_SERVICE)); if (match_counter == 1) { /* If we hit the low matches watermark, install a * less granular one. */ g_dbus_connection_call (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch", g_variant_new ("(s)", "type='signal',sender='" NM_DBUS_SERVICE "'"), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } if (match_counter) match_counter--; if (match_counter) return; /* Remove what this proxy added. */ match = g_strdup_printf ("type='signal',sender='" NM_DBUS_SERVICE "'," "interface='%s',path='%s'", g_dbus_proxy_get_interface_name (proxy), g_dbus_proxy_get_object_path (proxy)); g_dbus_connection_call (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RemoveMatch", g_variant_new ("(s)", match), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); g_free (match); }
void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, GDBusProxy *interface_proxy) { const gchar *interface_name; g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy)); g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy)); interface_name = g_dbus_proxy_get_interface_name (interface_proxy); _g_dbus_object_proxy_remove_interface (proxy, interface_name); g_hash_table_insert (proxy->priv->map_name_to_iface, g_strdup (interface_name), g_object_ref (interface_proxy)); g_signal_emit_by_name (proxy, "interface-added", interface_proxy); }
static void on_interface_removed (GDBusObjectManager *manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { CockpitDBusJson1 *self = user_data; cleanup_unref_object JsonBuilder *builder = prepare_builder ("interface-removed"); json_builder_begin_object (builder); json_builder_set_member_name (builder, "objpath"); json_builder_add_string_value (builder, g_dbus_object_get_object_path (object)); json_builder_set_member_name (builder, "iface_name"); json_builder_add_string_value (builder, g_dbus_proxy_get_interface_name (G_DBUS_PROXY (interface))); json_builder_end_object (builder); write_builder (self, builder); }
static void on_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, GStrv invalidated_properties, gpointer user_data) { CockpitObjectProxy *self = COCKPIT_OBJECT_PROXY (user_data); g_debug ("fakemanager: interface-proxy-properties-changed: %s %s", g_dbus_proxy_get_object_path (proxy), g_dbus_proxy_get_interface_name (proxy)); if (self->manager) { g_object_ref (self->manager); if (changed_properties) cockpit_fake_manager_scrape (self->manager, changed_properties); g_signal_emit (self->manager, sig_manager__interface_proxy_properties_changed, 0, self, proxy, changed_properties, invalidated_properties); g_object_unref (self->manager); } }
static gboolean gtk_application_impl_dbus_is_inhibited (GtkApplicationImpl *impl, GtkApplicationInhibitFlags flags) { GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl; GVariant *res; GError *error = NULL; gboolean inhibited; static gboolean warned = FALSE; if (dbus->sm_proxy == NULL) return FALSE; res = g_dbus_proxy_call_sync (dbus->sm_proxy, "IsInhibited", g_variant_new ("(u)", flags), G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error); if (error) { if (!warned) { g_warning ("Calling %s.IsInhibited failed: %s", g_dbus_proxy_get_interface_name (dbus->sm_proxy), error->message); warned = TRUE; } g_error_free (error); return FALSE; } g_variant_get (res, "(b)", &inhibited); g_variant_unref (res); return inhibited; }
static void on_poke_proxy (GObject *source_object, GAsyncResult *result, gpointer user_data) { PokeContext *poke = user_data; CockpitFakeManager *self = poke->manager; GError *error = NULL; GDBusProxy *proxy; g_assert (poke->outstanding > 0); poke->outstanding--; proxy = g_dbus_proxy_new_finish (result, &error); /* Bail fast if cancelled */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { if (poke->outstanding == 0) poke_context_finish (self, poke); return; } if (error) { g_warning ("Couldn't create proxy: %s", error->message); g_error_free (error); } else { g_debug ("fakemanager: proxy created: %s %s", poke->object_path, g_dbus_proxy_get_interface_name (proxy)); poke->added = g_list_prepend (poke->added, proxy); } if (poke->outstanding == 0) poke_apply_changes_and_finish (self, poke); }
static void on_proxy_signal (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { CockpitObjectProxy *self = COCKPIT_OBJECT_PROXY (user_data); g_debug ("fakemanager: interface-proxy-signal: %s %s %s", g_dbus_proxy_get_object_path (proxy), g_dbus_proxy_get_interface_name (proxy), signal_name); if (self->manager) { g_object_ref (self->manager); if (parameters) cockpit_fake_manager_scrape (self->manager, parameters); g_signal_emit (self->manager, sig_manager__interface_proxy_signal, 0, self, proxy, sender_name, signal_name, parameters); g_object_unref (self->manager); } }
static void on_interface_proxy_signal (GDBusObjectManager *manager, GDBusObjectProxy *object_proxy, GDBusProxy *interface_proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data) { CockpitDBusJson1 *self = user_data; cleanup_unref_object JsonBuilder *builder = prepare_builder ("interface-signal"); GVariantIter iter; GVariant *child; json_builder_begin_object (builder); json_builder_set_member_name (builder, "objpath"); json_builder_add_string_value (builder, g_dbus_object_get_object_path (G_DBUS_OBJECT (object_proxy))); json_builder_set_member_name (builder, "iface_name"); json_builder_add_string_value (builder, g_dbus_proxy_get_interface_name (interface_proxy)); json_builder_set_member_name (builder, "signal_name"); json_builder_add_string_value (builder, signal_name); json_builder_set_member_name (builder, "args"); json_builder_begin_array (builder); g_variant_iter_init (&iter, parameters); while ((child = g_variant_iter_next_value (&iter)) != NULL) { _json_builder_add_gvariant (builder, child); g_variant_unref (child); } json_builder_end_array (builder); json_builder_end_object (builder); write_builder (self, builder); }
static void CALEOnInterfaceProxyPropertiesChanged( GDBusObjectManagerClient * manager, GDBusObjectProxy * object_proxy, GDBusProxy * interface_proxy, GVariant * changed_properties, gchar const * const * invalidated_properties, gpointer user_data) { (void)manager; (void)object_proxy; (void)invalidated_properties; char const * const interface_name = g_dbus_proxy_get_interface_name(interface_proxy); bool const is_adapter_interface = (strcmp(BLUEZ_ADAPTER_INTERFACE, interface_name) == 0); if (!is_adapter_interface) { /* Only specific org.bluez.Adapter1 property changes are currently supported. */ return; } OIC_LOG_V(DEBUG, TAG, "%s properties Changed on %s:\n", interface_name, g_dbus_proxy_get_object_path(interface_proxy)); CALEContext * const context = user_data; GVariantIter iter; gchar const * key = NULL; GVariant * value = NULL; /** * @todo Since we're only looking up one value here, * i.e. "Powered", can't we just use * g_variant_lookup_value() instead of this while() loop? */ g_variant_iter_init(&iter, changed_properties); while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) { if (strcmp(key, "Powered") == 0) { /* Report a change in the availability of the bluetooth adapter. */ gboolean const powered = g_variant_get_boolean(value); CAAdapterState_t const status = (powered ? CA_ADAPTER_ENABLED : CA_ADAPTER_DISABLED); /** * @todo Should we acquire the context lock here to * prevent the @c CALEDeviceStateChangedCallback * from being potentially yanked out from under us * if the CA adapters are stopped/terminated as * we're about to invoke this callback? * * @todo Unfortunately the CA LE interface defined in * caleinterface.h assumes that only one BLE adapter * will exist on a given host. However, this * implementation can handle multiple BLE adapters. * The CA LE interface should be updated so that it * can handle multiple BLE adapters. */ context->on_device_state_changed(status); } #ifdef TB_LOG gchar * const s = g_variant_print(value, TRUE); OIC_LOG_V(DEBUG, TAG, " %s -> %s", key, s); g_free(s); #endif // TB_LOG g_variant_unref(value); } }
static gboolean cockpit_object_proxy_update (CockpitObjectProxy *self, GList *interfaces_to_add, GList *interfaces_to_remove) { const gchar *iface_name; GList *removed = NULL; GList *added = NULL; GList *l; g_return_val_if_fail (COCKPIT_IS_OBJECT_PROXY (self), FALSE); /* * First we update the object, then we emit the signals. In the * the future we'll need to eliminate races with use of generations. */ for (l = interfaces_to_add; l != NULL; l = g_list_next (l)) { iface_name = g_dbus_proxy_get_interface_name (l->data); if (!g_hash_table_lookup (self->interfaces, iface_name)) { g_debug ("fakemanager: interface-added: %s: %s", g_dbus_proxy_get_object_path (l->data), iface_name); g_hash_table_insert (self->interfaces, (gpointer)iface_name, g_object_ref (l->data)); added = g_list_prepend (added, l->data); g_signal_connect (l->data, "g-signal", G_CALLBACK (on_proxy_signal), self); g_signal_connect (l->data, "g-properties-changed", G_CALLBACK (on_properties_changed), self); } } for (l = interfaces_to_remove; l != NULL; l = g_list_next (l)) { iface_name = g_dbus_proxy_get_interface_name (l->data); /* * TODO: If we start allowing concurrent pokes for the same object path * then we'll need to double check here that we're removing the right * interface from the hash table. */ /* Caller holds a reference so this is safe */ if (g_hash_table_remove (self->interfaces, iface_name)) { g_debug ("fakemanager: interface-removed: %s: %s", g_dbus_proxy_get_object_path (l->data), iface_name); removed = g_list_prepend (removed, l->data); g_signal_handlers_disconnect_by_func (l->data, on_proxy_signal, self); g_signal_handlers_disconnect_by_func (l->data, on_properties_changed, self); } } for (l = added; l != NULL; l = g_list_next (l)) { g_signal_emit (self, sig_object__interface_added, 0, l->data); if (self->manager) g_signal_emit (self->manager, sig_manager__interface_added, 0, self, l->data); } g_list_free (added); for (l = removed; l != NULL; l = g_list_next (l)) { g_signal_emit (self, sig_object__interface_removed, 0, l->data); if (self->manager) g_signal_emit (self->manager, sig_manager__interface_removed, 0, self, l->data); } g_list_free (removed); return g_hash_table_size (self->interfaces) > 0; }
static void _setup_nfc_adapter(GTlmNfc *self, GDBusProxy *nfc_adapter) { GError* error = NULL; gboolean powered; gboolean polling; // for some reason the cached properties aren't updated, so we request them directly //GVariant* powered_v = g_dbus_proxy_get_cached_property(nfc_adapter, "Powered"); GVariant* powered_resp = g_dbus_connection_call_sync (self->system_bus, "org.neard", g_dbus_proxy_get_object_path(nfc_adapter) , "org.freedesktop.DBus.Properties", "Get", g_variant_new("(ss)", g_dbus_proxy_get_interface_name(nfc_adapter), "Powered" ), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (powered_resp == NULL) { g_debug("Powered property is absent on an adapter: %s", error->message); g_error_free (error); return; } GVariant* powered_v; g_variant_get_child(powered_resp, 0, "v", &powered_v); if (powered_v == NULL || !g_variant_is_of_type(powered_v, G_VARIANT_TYPE_BOOLEAN)) { g_debug("Error retrieving powered property"); return; } powered = g_variant_get_boolean(powered_v); g_variant_unref(powered_resp); //GVariant* polling_v = g_dbus_proxy_get_cached_property(nfc_adapter, "Polling"); GVariant* polling_resp = g_dbus_connection_call_sync (self->system_bus, "org.neard", g_dbus_proxy_get_object_path(nfc_adapter) , "org.freedesktop.DBus.Properties", "Get", g_variant_new("(ss)", g_dbus_proxy_get_interface_name(nfc_adapter), "Polling" ), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (polling_resp == NULL) { g_debug("Polling property is absent on an adapter: %s", error->message); g_error_free (error); return; } GVariant* polling_v; g_variant_get_child(polling_resp, 0, "v", &polling_v); if (polling_v == NULL || !g_variant_is_of_type(polling_v, G_VARIANT_TYPE_BOOLEAN)) { g_debug("Error retrieving polling property"); return; } polling = g_variant_get_boolean(polling_v); g_variant_unref(polling_resp); GVariant* response; if (powered == FALSE) { // switch power on response = g_dbus_connection_call_sync (self->system_bus, "org.neard", g_dbus_proxy_get_object_path(nfc_adapter) , "org.freedesktop.DBus.Properties", "Set", g_variant_new("(ssv)", g_dbus_proxy_get_interface_name(nfc_adapter), "Powered", g_variant_new_boolean(TRUE) ), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (response == NULL ) { g_debug("Error swithing NFC adapter on: %s", error->message); g_error_free (error); return; } g_variant_unref(response); g_debug("Switched NFC adapter on"); } else g_debug("Adapter already switched on"); if (polling == FALSE) { // start polling response = g_dbus_proxy_call_sync (nfc_adapter, "StartPollLoop", g_variant_new("(s)", "Initiator"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (response == NULL) { g_debug("Error starting NFC poll loop: %s", error->message); g_error_free (error); return; } g_variant_unref(response); g_debug("Started NFC poll loop"); } else g_debug("Adapter already in polling mode"); }
static guint gtk_application_impl_dbus_inhibit (GtkApplicationImpl *impl, GtkWindow *window, GtkApplicationInhibitFlags flags, const gchar *reason) { GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl; GVariant *res; GError *error = NULL; guint cookie; static gboolean warned = FALSE; if (dbus->sm_proxy) { res = g_dbus_proxy_call_sync (dbus->sm_proxy, "Inhibit", g_variant_new ("(s@usu)", dbus->application_id, window ? gtk_application_impl_dbus_get_window_system_id (dbus, window) : g_variant_new_uint32 (0), reason, flags), G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error); if (res) { g_variant_get (res, "(u)", &cookie); g_variant_unref (res); return cookie; } if (error) { if (!warned) { g_warning ("Calling %s.Inhibit failed: %s", g_dbus_proxy_get_interface_name (dbus->sm_proxy), error->message); warned = TRUE; } g_clear_error (&error); } } else if (dbus->inhibit_proxy) { GVariantBuilder options; g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&options, "{sv}", "reason", g_variant_new_string (reason)); res = g_dbus_proxy_call_sync (dbus->inhibit_proxy, "Inhibit", g_variant_new ("(su@a{sv})", "", /* window */ flags, g_variant_builder_end (&options)), G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error); if (res) { InhibitHandle *handle; handle = g_new (InhibitHandle, 1); handle->cookie = ++next_cookie; g_variant_get (res, "(o)", &handle->handle); g_variant_unref (res); dbus->inhibit_handles = g_slist_prepend (dbus->inhibit_handles, handle); return handle->cookie; } if (error) { if (!warned) { g_warning ("Calling %s.Inhibit failed: %s", g_dbus_proxy_get_interface_name (dbus->inhibit_proxy), error->message); warned = TRUE; } g_clear_error (&error); } } return 0; }
static gint is_interface_type(gconstpointer data, gconstpointer user_data) { GDBusProxy* proxy = (GDBusProxy*)data; const gchar* interface_name = g_dbus_proxy_get_interface_name(proxy); return g_strcmp0(interface_name, (const gchar*)user_data); }