mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-01-04 04:40:12 +01:00
modules: implement logind module and integrate with bluez monitor
This copies the logic of media-session's logind module and allows the bluez monitor to be active in only one user session at a time. This is especially useful to avoid interference between the gdm session and the actual user session, which momentarily both have wireplumber running when logging in/out. Fixes #54
This commit is contained in:
parent
7005c4518f
commit
a253aa4c49
7 changed files with 196 additions and 11 deletions
|
|
@ -79,6 +79,11 @@ else
|
|||
endif
|
||||
summary({'Lua version': lua_dep.version() + (system_lua ? ' (system)' : ' (built-in)')})
|
||||
|
||||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
libsystemd_dep = dependency('libsystemd',required: get_option('systemd'))
|
||||
summary({'systemd conf data': systemd.found(),
|
||||
'libsystemd': libsystemd_dep.found()}, bool_yn: true)
|
||||
|
||||
gnome = import('gnome')
|
||||
pkgconfig = import('pkgconfig')
|
||||
fs = import('fs')
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ option('system-lua-version',
|
|||
description: 'The system lua version to use or "auto" for auto-detection')
|
||||
option('systemd',
|
||||
type: 'feature', value: 'auto',
|
||||
description: 'Enable installing systemd units')
|
||||
description: 'Enable installing systemd units & logind integration')
|
||||
option('systemd-system-service',
|
||||
type : 'boolean', value : false,
|
||||
description: 'Install systemd system service file')
|
||||
|
|
|
|||
|
|
@ -176,3 +176,16 @@ shared_library(
|
|||
install_dir : wireplumber_module_dir,
|
||||
dependencies : [wp_dep, pipewire_dep],
|
||||
)
|
||||
|
||||
if libsystemd_dep.found()
|
||||
shared_library(
|
||||
'wireplumber-module-logind',
|
||||
[
|
||||
'module-logind.c',
|
||||
],
|
||||
c_args : [common_c_args, '-DG_LOG_DOMAIN="m-logind"'],
|
||||
install : true,
|
||||
install_dir : wireplumber_module_dir,
|
||||
dependencies : [wp_dep, pipewire_dep, libsystemd_dep],
|
||||
)
|
||||
endif
|
||||
|
|
|
|||
142
modules/module-logind.c
Normal file
142
modules/module-logind.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* WirePlumber
|
||||
*
|
||||
* Copyright © 2021 Collabora Ltd.
|
||||
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <wp/wp.h>
|
||||
#include <glib-unix.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#include <spa/utils/result.h>
|
||||
#include <spa/utils/string.h>
|
||||
|
||||
#define NAME "logind"
|
||||
|
||||
struct _WpLogind
|
||||
{
|
||||
WpPlugin parent;
|
||||
sd_login_monitor *monitor;
|
||||
GSource *source;
|
||||
char *state;
|
||||
};
|
||||
|
||||
enum {
|
||||
ACTION_GET_STATE,
|
||||
SIGNAL_STATE_CHANGED,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = {0};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (WpLogind, wp_logind, WP, LOGIND, WpPlugin)
|
||||
G_DEFINE_TYPE (WpLogind, wp_logind, WP_TYPE_PLUGIN)
|
||||
|
||||
static void
|
||||
wp_logind_init (WpLogind * self)
|
||||
{
|
||||
}
|
||||
|
||||
static gchar *
|
||||
wp_logind_get_state (WpLogind *self)
|
||||
{
|
||||
return g_strdup (self->state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wp_logind_source_ready (gint fd, GIOCondition condition, gpointer user_data)
|
||||
{
|
||||
WpLogind *self = WP_LOGIND (user_data);
|
||||
sd_login_monitor_flush (self->monitor);
|
||||
{
|
||||
char *state = NULL;
|
||||
sd_uid_get_state (getuid(), &state);
|
||||
if (g_strcmp0 (state, self->state) != 0) {
|
||||
char *tmp = state;
|
||||
state = self->state;
|
||||
self->state = tmp;
|
||||
g_signal_emit (self, signals[SIGNAL_STATE_CHANGED], 0, self->state);
|
||||
}
|
||||
free (state);
|
||||
}
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wp_logind_enable (WpPlugin * plugin, WpTransition * transition)
|
||||
{
|
||||
WpLogind *self = WP_LOGIND (plugin);
|
||||
int res = 0;
|
||||
|
||||
if ((res = sd_login_monitor_new (NULL, &self->monitor)) < 0) {
|
||||
wp_transition_return_error (transition, g_error_new (G_IO_ERROR,
|
||||
g_io_error_from_errno (-res),
|
||||
"failed to start systemd logind monitor: %d (%s)",
|
||||
res, spa_strerror(res)));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((res = sd_uid_get_state (getuid(), &self->state)) < 0) {
|
||||
wp_transition_return_error (transition, g_error_new (G_IO_ERROR,
|
||||
g_io_error_from_errno (-res),
|
||||
"failed to get systemd login state: %d (%s)",
|
||||
res, spa_strerror(res)));
|
||||
g_clear_pointer (&self->monitor, sd_login_monitor_unref);
|
||||
return;
|
||||
}
|
||||
|
||||
self->source = g_unix_fd_source_new (
|
||||
sd_login_monitor_get_fd (self->monitor),
|
||||
sd_login_monitor_get_events (self->monitor));
|
||||
g_source_set_callback (self->source, G_SOURCE_FUNC (wp_logind_source_ready),
|
||||
self, NULL);
|
||||
|
||||
g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (plugin));
|
||||
GMainContext *context = wp_core_get_g_main_context (core);
|
||||
g_source_attach (self->source, context);
|
||||
|
||||
wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_logind_disable (WpPlugin * plugin)
|
||||
{
|
||||
WpLogind *self = WP_LOGIND (plugin);
|
||||
|
||||
g_clear_pointer (&self->state, free);
|
||||
g_source_destroy (self->source);
|
||||
g_clear_pointer (&self->source, g_source_unref);
|
||||
g_clear_pointer (&self->monitor, sd_login_monitor_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_logind_class_init (WpLogindClass * klass)
|
||||
{
|
||||
WpPluginClass *plugin_class = (WpPluginClass *) klass;
|
||||
|
||||
plugin_class->enable = wp_logind_enable;
|
||||
plugin_class->disable = wp_logind_disable;
|
||||
|
||||
signals[ACTION_GET_STATE] = g_signal_new_class_handler (
|
||||
"get-state", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
(GCallback) wp_logind_get_state,
|
||||
NULL, NULL, NULL, G_TYPE_STRING, 0);
|
||||
|
||||
signals[SIGNAL_STATE_CHANGED] = g_signal_new (
|
||||
"state-changed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
}
|
||||
|
||||
WP_PLUGIN_EXPORT gboolean
|
||||
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
|
||||
{
|
||||
wp_plugin_register (g_object_new (wp_logind_get_type (),
|
||||
"name", NAME,
|
||||
"core", core,
|
||||
NULL));
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -7,4 +7,6 @@ function bluez_monitor.enable()
|
|||
properties = bluez_monitor.properties,
|
||||
rules = bluez_monitor.rules,
|
||||
})
|
||||
|
||||
load_module("logind")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,13 +125,39 @@ function createDevice(parent, id, type, factory, properties)
|
|||
end
|
||||
end
|
||||
|
||||
local monitor_props = config.properties or {}
|
||||
monitor_props["api.bluez5.connection-info"] = true
|
||||
function createMonitor()
|
||||
local monitor_props = config.properties or {}
|
||||
monitor_props["api.bluez5.connection-info"] = true
|
||||
|
||||
monitor = SpaDevice("api.bluez5.enum.dbus", monitor_props)
|
||||
if monitor then
|
||||
monitor:connect("create-object", createDevice)
|
||||
local monitor = SpaDevice("api.bluez5.enum.dbus", monitor_props)
|
||||
if monitor then
|
||||
monitor:connect("create-object", createDevice)
|
||||
else
|
||||
Log.message("PipeWire's BlueZ SPA missing or broken. Bluetooth not supported.")
|
||||
return nil
|
||||
end
|
||||
monitor:activate(Feature.SpaDevice.ENABLED)
|
||||
else
|
||||
Log.message("PipeWire's BlueZ SPA missing or broken. Bluetooth not supported.")
|
||||
|
||||
return monitor
|
||||
end
|
||||
|
||||
logind_plugin = Plugin.find("logind")
|
||||
if logind_plugin then
|
||||
-- if logind support is enabled, activate
|
||||
-- the monitor only when the seat is active
|
||||
function startStopMonitor(seat_state)
|
||||
Log.info(logind_plugin, "Seat state changed: " .. seat_state)
|
||||
|
||||
if seat_state == "active" then
|
||||
monitor = createMonitor()
|
||||
elseif monitor then
|
||||
monitor:deactivate(Feature.SpaDevice.ENABLED)
|
||||
monitor = nil
|
||||
end
|
||||
end
|
||||
|
||||
logind_plugin:connect("state-changed", function(p, s) startStopMonitor(s) end)
|
||||
startStopMonitor(logind_plugin:call("get-state"))
|
||||
else
|
||||
monitor = createMonitor()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
summary({'systemd conf data': systemd.found()}, bool_yn: true)
|
||||
|
||||
if systemd.found()
|
||||
systemd_config = configuration_data()
|
||||
systemd_config.set('WP_BINARY', wireplumber_bin_dir / 'wireplumber')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue