mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	flatpak: use support dbus connection
This commit is contained in:
		
							parent
							
								
									0b7c3e7407
								
							
						
					
					
						commit
						82ea32bcdf
					
				
					 1 changed files with 16 additions and 201 deletions
				
			
		| 
						 | 
					@ -27,7 +27,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <dbus/dbus.h>
 | 
					#include <spa/support/dbus.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pipewire/core.h"
 | 
					#include "pipewire/core.h"
 | 
				
			||||||
#include "pipewire/interfaces.h"
 | 
					#include "pipewire/interfaces.h"
 | 
				
			||||||
| 
						 | 
					@ -41,14 +41,13 @@ struct impl {
 | 
				
			||||||
	struct pw_type *type;
 | 
						struct pw_type *type;
 | 
				
			||||||
	struct pw_properties *properties;
 | 
						struct pw_properties *properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_dbus_connection *conn;
 | 
				
			||||||
	DBusConnection *bus;
 | 
						DBusConnection *bus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_hook core_listener;
 | 
						struct spa_hook core_listener;
 | 
				
			||||||
	struct spa_hook module_listener;
 | 
						struct spa_hook module_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_list client_list;
 | 
						struct spa_list client_list;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct spa_source *dispatch_event;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct resource;
 | 
					struct resource;
 | 
				
			||||||
| 
						 | 
					@ -543,188 +542,6 @@ static const struct pw_core_events core_events = {
 | 
				
			||||||
	.global_removed = core_global_removed,
 | 
						.global_removed = core_global_removed,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dispatch_cb(void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (dbus_connection_dispatch(impl->bus) == DBUS_DISPATCH_COMPLETE)
 | 
					 | 
				
			||||||
		pw_loop_enable_idle(pw_core_get_main_loop(impl->core), impl->dispatch_event, false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void dispatch_status(DBusConnection *conn, DBusDispatchStatus status, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pw_loop_enable_idle(pw_core_get_main_loop(impl->core),
 | 
					 | 
				
			||||||
			    impl->dispatch_event, status == DBUS_DISPATCH_COMPLETE ? false : true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline enum spa_io dbus_to_io(DBusWatch *watch)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	enum spa_io mask;
 | 
					 | 
				
			||||||
	unsigned int flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* no watch flags for disabled watches */
 | 
					 | 
				
			||||||
	if (!dbus_watch_get_enabled(watch))
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	flags = dbus_watch_get_flags(watch);
 | 
					 | 
				
			||||||
	mask = SPA_IO_HUP | SPA_IO_ERR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (flags & DBUS_WATCH_READABLE)
 | 
					 | 
				
			||||||
		mask |= SPA_IO_IN;
 | 
					 | 
				
			||||||
	if (flags & DBUS_WATCH_WRITABLE)
 | 
					 | 
				
			||||||
		mask |= SPA_IO_OUT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return mask;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline unsigned int io_to_dbus(enum spa_io mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsigned int flags = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (mask & SPA_IO_IN)
 | 
					 | 
				
			||||||
		flags |= DBUS_WATCH_READABLE;
 | 
					 | 
				
			||||||
	if (mask & SPA_IO_OUT)
 | 
					 | 
				
			||||||
		flags |= DBUS_WATCH_WRITABLE;
 | 
					 | 
				
			||||||
	if (mask & SPA_IO_HUP)
 | 
					 | 
				
			||||||
		flags |= DBUS_WATCH_HANGUP;
 | 
					 | 
				
			||||||
	if (mask & SPA_IO_ERR)
 | 
					 | 
				
			||||||
		flags |= DBUS_WATCH_ERROR;
 | 
					 | 
				
			||||||
	return flags;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
handle_io_event(void *userdata, int fd, enum spa_io mask)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DBusWatch *watch = userdata;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dbus_watch_get_enabled(watch)) {
 | 
					 | 
				
			||||||
		pw_log_warn("Asked to handle disabled watch: %p %i", (void *) watch, fd);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dbus_watch_handle(watch, io_to_dbus(mask));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dbus_bool_t add_watch(DBusWatch *watch, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct spa_source *source;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pw_log_debug("add watch %p %d", watch, dbus_watch_get_unix_fd(watch));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* we dup because dbus tends to add the same fd multiple times and our epoll
 | 
					 | 
				
			||||||
	 * implementation does not like that */
 | 
					 | 
				
			||||||
	source = pw_loop_add_io(pw_core_get_main_loop(impl->core),
 | 
					 | 
				
			||||||
				dup(dbus_watch_get_unix_fd(watch)),
 | 
					 | 
				
			||||||
				dbus_to_io(watch), true, handle_io_event, watch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbus_watch_set_data(watch, source, NULL);
 | 
					 | 
				
			||||||
	return TRUE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void remove_watch(DBusWatch *watch, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct spa_source *source;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((source = dbus_watch_get_data(watch)))
 | 
					 | 
				
			||||||
		pw_loop_destroy_source(pw_core_get_main_loop(impl->core), source);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void toggle_watch(DBusWatch *watch, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct spa_source *source;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	source = dbus_watch_get_data(watch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pw_loop_update_io(pw_core_get_main_loop(impl->core), source, dbus_to_io(watch));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
struct timeout_data {
 | 
					 | 
				
			||||||
	struct spa_source *source;
 | 
					 | 
				
			||||||
	struct impl *impl;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
handle_timer_event(void *userdata, uint64_t expirations)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	DBusTimeout *timeout = userdata;
 | 
					 | 
				
			||||||
	uint64_t t;
 | 
					 | 
				
			||||||
	struct timespec ts;
 | 
					 | 
				
			||||||
	struct timeout_data *data = dbus_timeout_get_data(timeout);
 | 
					 | 
				
			||||||
	struct impl *impl = data->impl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (dbus_timeout_get_enabled(timeout)) {
 | 
					 | 
				
			||||||
		t = dbus_timeout_get_interval(timeout) * SPA_NSEC_PER_MSEC;
 | 
					 | 
				
			||||||
		ts.tv_sec = t / SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
		ts.tv_nsec = t % SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
		pw_loop_update_timer(pw_core_get_main_loop(impl->core),
 | 
					 | 
				
			||||||
				     data->source, &ts, NULL, false);
 | 
					 | 
				
			||||||
		dbus_timeout_handle(timeout);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dbus_bool_t add_timeout(DBusTimeout *timeout, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct timespec ts;
 | 
					 | 
				
			||||||
	struct timeout_data *data;
 | 
					 | 
				
			||||||
	uint64_t t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!dbus_timeout_get_enabled(timeout))
 | 
					 | 
				
			||||||
		return FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data = calloc(1, sizeof(struct timeout_data));
 | 
					 | 
				
			||||||
	data->impl = impl;
 | 
					 | 
				
			||||||
	data->source = pw_loop_add_timer(pw_core_get_main_loop(impl->core), handle_timer_event, timeout);
 | 
					 | 
				
			||||||
	dbus_timeout_set_data(timeout, data, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t = dbus_timeout_get_interval(timeout) * SPA_NSEC_PER_MSEC;
 | 
					 | 
				
			||||||
	ts.tv_sec = t / SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
	ts.tv_nsec = t % SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
	pw_loop_update_timer(pw_core_get_main_loop(impl->core), data->source, &ts, NULL, false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return TRUE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void remove_timeout(DBusTimeout *timeout, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct timeout_data *data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ((data = dbus_timeout_get_data(timeout))) {
 | 
					 | 
				
			||||||
		pw_loop_destroy_source(pw_core_get_main_loop(impl->core), data->source);
 | 
					 | 
				
			||||||
		free(data);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void toggle_timeout(DBusTimeout *timeout, void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
	struct timeout_data *data;
 | 
					 | 
				
			||||||
	struct timespec ts, *tsp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data = dbus_timeout_get_data(timeout);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (dbus_timeout_get_enabled(timeout)) {
 | 
					 | 
				
			||||||
		uint64_t t = dbus_timeout_get_interval(timeout) * SPA_NSEC_PER_MSEC;
 | 
					 | 
				
			||||||
		ts.tv_sec = t / SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
		ts.tv_nsec = t % SPA_NSEC_PER_SEC;
 | 
					 | 
				
			||||||
		tsp = &ts;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		tsp = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pw_loop_update_timer(pw_core_get_main_loop(impl->core), data->source, tsp, NULL, false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void wakeup_main(void *userdata)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = userdata;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pw_loop_enable_idle(pw_core_get_main_loop(impl->core), impl->dispatch_event, true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void module_destroy(void *data)
 | 
					static void module_destroy(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = data;
 | 
						struct impl *impl = data;
 | 
				
			||||||
| 
						 | 
					@ -733,14 +550,11 @@ static void module_destroy(void *data)
 | 
				
			||||||
	spa_hook_remove(&impl->core_listener);
 | 
						spa_hook_remove(&impl->core_listener);
 | 
				
			||||||
	spa_hook_remove(&impl->module_listener);
 | 
						spa_hook_remove(&impl->module_listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_connection_close(impl->bus);
 | 
						spa_dbus_connection_destroy(impl->conn);
 | 
				
			||||||
	dbus_connection_unref(impl->bus);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_for_each_safe(info, t, &impl->client_list, link)
 | 
						spa_list_for_each_safe(info, t, &impl->client_list, link)
 | 
				
			||||||
		client_info_free(info);
 | 
							client_info_free(info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_loop_destroy_source(pw_core_get_main_loop(impl->core), impl->dispatch_event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (impl->properties)
 | 
						if (impl->properties)
 | 
				
			||||||
		pw_properties_free(impl->properties);
 | 
							pw_properties_free(impl->properties);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -757,8 +571,15 @@ static int module_init(struct pw_module *module, struct pw_properties *propertie
 | 
				
			||||||
	struct pw_core *core = pw_module_get_core(module);
 | 
						struct pw_core *core = pw_module_get_core(module);
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
	DBusError error;
 | 
						DBusError error;
 | 
				
			||||||
 | 
						struct spa_dbus *dbus;
 | 
				
			||||||
 | 
						const struct spa_support *support;
 | 
				
			||||||
 | 
						uint32_t n_support;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_error_init(&error);
 | 
						support = pw_core_get_support(core, &n_support);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbus = spa_support_find(support, n_support, SPA_TYPE__DBus);
 | 
				
			||||||
 | 
					        if (dbus == NULL)
 | 
				
			||||||
 | 
					                return -ENOTSUP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
| 
						 | 
					@ -770,19 +591,13 @@ static int module_init(struct pw_module *module, struct pw_properties *propertie
 | 
				
			||||||
	impl->type = pw_core_get_type(core);
 | 
						impl->type = pw_core_get_type(core);
 | 
				
			||||||
	impl->properties = properties;
 | 
						impl->properties = properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->bus = dbus_bus_get_private(DBUS_BUS_SESSION, &error);
 | 
						dbus_error_init(&error);
 | 
				
			||||||
	if (impl->bus == NULL)
 | 
					
 | 
				
			||||||
 | 
						impl->conn = spa_dbus_get_connection(dbus, DBUS_BUS_SESSION, &error);
 | 
				
			||||||
 | 
						if (impl->conn == NULL)
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->dispatch_event = pw_loop_add_idle(pw_core_get_main_loop(core), false, dispatch_cb, impl);
 | 
						impl->bus = spa_dbus_connection_get(impl->conn);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbus_connection_set_exit_on_disconnect(impl->bus, false);
 | 
					 | 
				
			||||||
	dbus_connection_set_dispatch_status_function(impl->bus, dispatch_status, impl, NULL);
 | 
					 | 
				
			||||||
	dbus_connection_set_watch_functions(impl->bus, add_watch, remove_watch, toggle_watch, impl,
 | 
					 | 
				
			||||||
					    NULL);
 | 
					 | 
				
			||||||
	dbus_connection_set_timeout_functions(impl->bus, add_timeout, remove_timeout,
 | 
					 | 
				
			||||||
					      toggle_timeout, impl, NULL);
 | 
					 | 
				
			||||||
	dbus_connection_set_wakeup_main_function(impl->bus, wakeup_main, impl, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_init(&impl->client_list);
 | 
						spa_list_init(&impl->client_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue