From a4f16a98f0188fda8010d5847f7b136bcb0d75a7 Mon Sep 17 00:00:00 2001 From: Ashok Sidipotu Date: Wed, 27 Apr 2022 18:18:03 +0530 Subject: [PATCH] main: Add support for deps flag in loading modules - support loading modules dependent on wireplumber settings in JSON config. - load the settings module before parsing wireplumber.components, so that dependencies can be fetched during parsing. - access lua scripts are switched to JSON based config and lua configs are removed. --- lib/wp/settings.c | 7 +- modules/module-lua-scripting/api/api.c | 12 +-- modules/module-lua-scripting/module.c | 2 + modules/module-settings.c | 3 +- src/config/main.lua.d/20-default-access.lua | 19 ---- src/config/main.lua.d/90-enable-all.lua | 3 - src/config/wireplumber.conf | 9 +- src/main.c | 106 ++++++++++++-------- src/scripts/access/access-default.lua | 29 +----- 9 files changed, 86 insertions(+), 104 deletions(-) delete mode 100644 src/config/main.lua.d/20-default-access.lua diff --git a/lib/wp/settings.c b/lib/wp/settings.c index 93ab7177..708b6d1b 100644 --- a/lib/wp/settings.c +++ b/lib/wp/settings.c @@ -114,8 +114,7 @@ gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule, g_return_val_if_fail (rule, false); g_return_val_if_fail (client_props, false); - wp_debug_object (self, "applying rule(%s) for client props(%d)", - rule, wp_properties_get_count (client_props)); + wp_debug_object (self, "applying rule(%s) for client props", rule); for (guint i = 0; i < self->rules->len; i++) { Rule *r = g_ptr_array_index (self->rules, i); @@ -135,8 +134,8 @@ gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule, else wp_properties_add (client_props, m->actions); - wp_debug_object (self, ". match found with actions(%d)", - wp_properties_get_count(m->actions)); + wp_debug_object (self, ". match found for rule(%s) with actions" + "(%d)", rule, wp_properties_get_count(m->actions)); return TRUE; } diff --git a/modules/module-lua-scripting/api/api.c b/modules/module-lua-scripting/api/api.c index 479d9eb4..12d9bb10 100644 --- a/modules/module-lua-scripting/api/api.c +++ b/modules/module-lua-scripting/api/api.c @@ -1476,12 +1476,12 @@ static gboolean get_boolean (lua_State *L) { const char *setting = luaL_checkstring (L, 1); - const char *metadata_name = NULL; + const char *m = NULL; if (lua_type (L, 2) == LUA_TSTRING) - metadata_name = luaL_checkstring (L, 2); + m = luaL_checkstring (L, 2); - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), metadata_name); + g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m); if (s) { @@ -1497,14 +1497,14 @@ static gboolean apply_rule (lua_State *L) { const char *r = luaL_checkstring (L, 1); - const char *metadata_name = NULL; + const char *m = NULL; g_autoptr (WpProperties) cp = wplua_table_to_properties (L, 2); g_autoptr (WpProperties) ap = wp_properties_new_empty (); if (lua_type (L, -1) == LUA_TSTRING) - metadata_name = luaL_checkstring (L, -1); + m = luaL_checkstring (L, -1); - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), metadata_name); + g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m); if (s) { diff --git a/modules/module-lua-scripting/module.c b/modules/module-lua-scripting/module.c index 2f1019b9..c1554458 100644 --- a/modules/module-lua-scripting/module.c +++ b/modules/module-lua-scripting/module.c @@ -56,6 +56,7 @@ wp_lua_scripting_package_searcher (lua_State *L) lua_pushcfunction (L, wp_lua_scripting_package_loader); /* 2. loader data (param to 1) */ + wp_debug ("Executing script %s", script); if (!wplua_load_path (L, script, &error)) { lua_pop (L, 1); lua_pushstring (L, error->message); @@ -206,6 +207,7 @@ wp_lua_scripting_plugin_load (WpComponentLoader * cl, const gchar * component, wp_plugin_register (g_steal_pointer (&script)); } else { /* keep in a list and delay registering until the plugin is enabled */ + wp_debug ("queing script %s", filename); g_ptr_array_add (self->scripts, g_steal_pointer (&script)); } return TRUE; diff --git a/modules/module-settings.c b/modules/module-settings.c index 780e235c..833a32e5 100644 --- a/modules/module-settings.c +++ b/modules/module-settings.c @@ -145,7 +145,6 @@ do_parse_settings (void *data, const char *location, g_autoptr (WpIterator) iter = wp_spa_json_new_iterator (json); g_auto (GValue) item = G_VALUE_INIT; - if (!wp_spa_json_is_object (json)) { /* "wireplumber.settings" section has to be a JSON object element. */ wp_transition_return_error (transition, g_error_new ( @@ -226,7 +225,7 @@ on_metadata_activated (WpMetadata * m, GAsyncResult * res, gpointer user_data) */ wp_transition_return_error (transition, g_error_new ( WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, - "No settings present in the context conf file: settings" + "No settings present in the context conf file: settings " "are not loaded")); return; } diff --git a/src/config/main.lua.d/20-default-access.lua b/src/config/main.lua.d/20-default-access.lua deleted file mode 100644 index 0a7eb955..00000000 --- a/src/config/main.lua.d/20-default-access.lua +++ /dev/null @@ -1,19 +0,0 @@ -default_access = {} -default_access.properties = {} -default_access.rules = {} - -function default_access.enable() - if default_access.enabled == false then - return - end - - load_access("default", { - rules = default_access.rules - }) - - if default_access.properties["enable-flatpak-portal"] then - -- Enables portal permissions via org.freedesktop.impl.portal.PermissionStore - load_module("portal-permissionstore") - load_access("portal") - end -end diff --git a/src/config/main.lua.d/90-enable-all.lua b/src/config/main.lua.d/90-enable-all.lua index 1aa194df..490d8b28 100644 --- a/src/config/main.lua.d/90-enable-all.lua +++ b/src/config/main.lua.d/90-enable-all.lua @@ -2,9 +2,6 @@ -- dynamic properties of pipewire objects in RAM load_module("metadata") --- Default client access policy -default_access.enable() - -- Load devices alsa_monitor.enable() v4l2_monitor.enable() diff --git a/src/config/wireplumber.conf b/src/config/wireplumber.conf index f4c7558b..5616a30f 100644 --- a/src/config/wireplumber.conf +++ b/src/config/wireplumber.conf @@ -85,11 +85,9 @@ wireplumber.components = [ # The lua scripting engine { name = libwireplumber-module-lua-scripting, type = module } - # Parses all the wireplumber settings in the .conf file, loads them into a - # "sm-settings" pipewire metadata and updates the settings to a state file, - # when persitent behavior is enabled. - - { name = libwireplumber-module-settings, type = module } + { name = access/access-default.lua, type = script/lua } + { name = libwireplumber-module-portal-permissionstore , type = module, deps = access.enable-flatpak-portal } + { name = access/access-portal.lua, type = script/lua, deps = access.enable-flatpak-portal } # The lua configuration file(s) # Other components are loaded from there @@ -137,6 +135,7 @@ wireplumber.settings = { # till the time the setting is set to false. # persistent.settings = false + access.enable-flatpak-portal = true access = [ { diff --git a/src/main.c b/src/main.c index d3e5df51..6e794c5a 100644 --- a/src/main.c +++ b/src/main.c @@ -46,10 +46,10 @@ struct _WpInitTransition }; enum { - STEP_LOAD_COMPONENTS = WP_TRANSITION_STEP_CUSTOM_START, - STEP_CONNECT, - STEP_CHECK_MEDIA_SESSION, + STEP_CONNECT = WP_TRANSITION_STEP_CUSTOM_START, STEP_ACTIVATE_SETTINGS, + STEP_LOAD_COMPONENTS, + STEP_CHECK_MEDIA_SESSION, STEP_ACTIVATE_PLUGINS, STEP_ACTIVATE_SCRIPTS, STEP_CLEANUP, @@ -68,11 +68,11 @@ static guint wp_init_transition_get_next_step (WpTransition * transition, guint step) { switch (step) { - case WP_TRANSITION_STEP_NONE: return STEP_LOAD_COMPONENTS; - case STEP_LOAD_COMPONENTS: return STEP_CONNECT; - case STEP_CONNECT: return STEP_CHECK_MEDIA_SESSION; - case STEP_CHECK_MEDIA_SESSION:return STEP_ACTIVATE_SETTINGS; - case STEP_ACTIVATE_SETTINGS: return STEP_ACTIVATE_PLUGINS; + case WP_TRANSITION_STEP_NONE: return STEP_CONNECT; + case STEP_CONNECT: return STEP_ACTIVATE_SETTINGS; + case STEP_ACTIVATE_SETTINGS: return STEP_LOAD_COMPONENTS; + case STEP_LOAD_COMPONENTS: return STEP_CHECK_MEDIA_SESSION; + case STEP_CHECK_MEDIA_SESSION:return STEP_ACTIVATE_PLUGINS; case STEP_CLEANUP: return WP_TRANSITION_STEP_NONE; case STEP_ACTIVATE_PLUGINS: { @@ -147,6 +147,7 @@ do_load_components(void *data, const char *location, const char *section, g_autoptr (WpSpaJson) json = NULL; g_autoptr (WpIterator) it = NULL; g_auto (GValue) item = G_VALUE_INIT; + g_autoptr (WpSettings) settings = wp_settings_get_instance (core, NULL); GError *error = NULL; json = wp_spa_json_new_from_stringn (str, len); @@ -163,6 +164,7 @@ do_load_components(void *data, const char *location, const char *section, WpSpaJson *o = g_value_get_boxed (&item); g_autofree gchar *name = NULL; g_autofree gchar *type = NULL; + g_autofree gchar *deps = NULL; if (!wp_spa_json_is_object (o) || !wp_spa_json_object_get (o, @@ -174,6 +176,15 @@ do_load_components(void *data, const char *location, const char *section, "component must have both a 'name' and a 'type'")); return -EINVAL; } + + if (wp_spa_json_object_get (o, "deps", "s", &deps, NULL) && deps) { + if (!wp_settings_get_boolean (settings, deps)) {; + wp_info ("deps(%s) not met for component(%s), skip loading it", + deps, name); + continue; + } + } + if (!wp_core_load_component (core, name, type, NULL, &error)) { wp_transition_return_error (transition, error); return -EINVAL; @@ -228,25 +239,13 @@ wp_init_transition_execute_step (WpTransition * transition, guint step) WpCore *core = wp_transition_get_source_object (transition); struct pw_context *pw_ctx = wp_core_get_pw_context (core); const struct pw_properties *props = pw_context_get_properties (pw_ctx); + GError *error = NULL; switch (step) { - case STEP_LOAD_COMPONENTS: { - struct data data = { .transition = transition }; - - if (pw_context_conf_section_for_each(pw_ctx, "wireplumber.components", - do_load_components, &data) < 0) - return; - if (data.count == 0) { - wp_transition_return_error (transition, g_error_new ( - WP_DOMAIN_DAEMON, WP_EXIT_CONFIG, - "No components configured in the context conf file; nothing to do")); - return; - } - wp_transition_advance (transition); - break; - } case STEP_CONNECT: { + wp_info_object (self, "Core connect..."); + g_signal_connect_object (core, "connected", G_CALLBACK (wp_transition_advance), transition, G_CONNECT_SWAPPED); @@ -283,6 +282,50 @@ wp_init_transition_execute_step (WpTransition * transition, guint step) break; } + case STEP_ACTIVATE_SETTINGS: { + + wp_info_object (self, "Activating settings..."); + + /* load settings module */ + if (!wp_core_load_component (core, "libwireplumber-module-settings", + "module", NULL, &error)) { + wp_transition_return_error (transition, error); + return; + } + + /* get handle to module to settings module/plugin & activate it */ + WpPlugin *p = wp_plugin_find (core, "settings"); + if (!p) { + wp_transition_return_error (transition, g_error_new ( + WP_DOMAIN_DAEMON, WP_EXIT_CONFIG, + "unable to find settings plugin")); + return; + } + + wp_object_activate (WP_OBJECT (p), WP_OBJECT_FEATURES_ALL, NULL, + (GAsyncReadyCallback) on_settings_plugin_ready, self); + + break; + } + + case STEP_LOAD_COMPONENTS: { + struct data data = { .transition = transition }; + + wp_info_object (self, "Load Wireplumber Components..."); + + if (pw_context_conf_section_for_each(pw_ctx, "wireplumber.components", + do_load_components, &data) < 0) + return; + if (data.count == 0) { + wp_transition_return_error (transition, g_error_new ( + WP_DOMAIN_DAEMON, WP_EXIT_CONFIG, + "No components configured in the context conf file; nothing to do")); + return; + } + wp_transition_advance (transition); + break; + } + case STEP_CHECK_MEDIA_SESSION: { wp_info_object (self, "Checking for session manager conflicts..."); @@ -296,23 +339,6 @@ wp_init_transition_execute_step (WpTransition * transition, guint step) break; } - case STEP_ACTIVATE_SETTINGS: { - /* find and activate settings plugin */ - WpPlugin *p = wp_plugin_find (core, "settings"); - if (!p) { - wp_transition_return_error (transition, g_error_new ( - WP_DOMAIN_DAEMON, WP_EXIT_CONFIG, - "unable to find settings plugin")); - return; - } - wp_info_object (self, "Activating wpsettings plugin"); - - wp_object_activate (WP_OBJECT (p), WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_settings_plugin_ready, self); - - break; - } - case STEP_ACTIVATE_PLUGINS: { const char *engine = pw_properties_get (props, "wireplumber.script-engine"); diff --git a/src/scripts/access/access-default.lua b/src/scripts/access/access-default.lua index 0fac87b7..a6055ffb 100644 --- a/src/scripts/access/access-default.lua +++ b/src/scripts/access/access-default.lua @@ -5,32 +5,11 @@ -- -- SPDX-License-Identifier: MIT -local config = ... or {} - --- preprocess rules and create Interest objects -for _, r in ipairs(config.rules or {}) do - r.interests = {} - for _, i in ipairs(r.matches) do - local interest_desc = { type = "properties" } - for _, c in ipairs(i) do - c.type = "pw" - table.insert(interest_desc, Constraint(c)) - end - local interest = Interest(interest_desc) - table.insert(r.interests, interest) - end - r.matches = nil -end - function rulesGetDefaultPermissions(properties) - for _, r in ipairs(config.rules or {}) do - if r.default_permissions then - for _, interest in ipairs(r.interests) do - if interest:matches(properties) then - return r.default_permissions - end - end - end + local matched, mprops = Settings.apply_rule ("access", properties) + + if (matched and mprops["default_permissions"]) then + return mprops["default_permissions"] end end