From 360e0b3eaf499f865ad9ce1229d3cb51c3a11d9b Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Tue, 10 Jan 2023 09:11:15 -0500 Subject: [PATCH] scripts: use WpConf API to get configuration values This patch also moves nested configuration objects that are not considered settings from the wireplumber.settings section to its own configuration section (eg the rules array, the spa plugin properties, etc...). This allows those objects to be merged with other same sections defined in other files. --- lib/wp/settings.c | 422 +------------------ lib/wp/settings.h | 20 - modules/module-lua-scripting/api/api.c | 159 ------- src/config/wireplumber.conf.d/access.conf | 79 ++-- src/config/wireplumber.conf.d/alsa.conf | 285 +++++++------ src/config/wireplumber.conf.d/bluetooth.conf | 319 +++++++------- src/config/wireplumber.conf.d/device.conf | 20 - src/config/wireplumber.conf.d/endpoint.conf | 180 ++++---- src/config/wireplumber.conf.d/libcamera.conf | 84 ++-- src/config/wireplumber.conf.d/policy.conf | 12 +- src/config/wireplumber.conf.d/stream.conf | 35 +- src/config/wireplumber.conf.d/v4l2.conf | 80 ++-- src/scripts/client/access-default.lua | 3 +- src/scripts/lib/common-utils.lua | 2 +- src/scripts/monitors/alsa-midi.lua | 9 +- src/scripts/monitors/alsa.lua | 22 +- src/scripts/monitors/bluez-midi.lua | 12 +- src/scripts/monitors/bluez.lua | 13 +- src/scripts/monitors/libcamera.lua | 4 +- src/scripts/monitors/v4l2.lua | 4 +- src/scripts/policy-bluetooth.lua | 35 +- src/scripts/policy-endpoint-client-links.lua | 6 +- src/scripts/policy-endpoint-client.lua | 4 +- src/scripts/policy-endpoint-device.lua | 2 +- src/scripts/static-endpoints.lua | 4 +- tests/wp/settings.c | 199 --------- tests/wplua/scripts/settings.lua | 167 +------- 27 files changed, 594 insertions(+), 1587 deletions(-) diff --git a/lib/wp/settings.c b/lib/wp/settings.c index 9a195134..7d121d45 100644 --- a/lib/wp/settings.c +++ b/lib/wp/settings.c @@ -8,11 +8,11 @@ #define G_LOG_DOMAIN "wp-settings" -#include - +#include "core.h" #include "settings.h" #include "metadata.h" #include "log.h" +#include "object-manager.h" #include "private/registry.h" /*! \defgroup wpsettings WpSettings */ @@ -20,8 +20,8 @@ * \struct WpSettings * * WpSettings loads and parses the "sm-settings" (default value) metadata, which - * contains wireplumber settings and rules. It provides APIs to its clients - * (modules, lua scripts etc) to access and change them. + * contains wireplumber settings. It provides APIs to its clients (modules, lua + * scripts etc) to access and change them. * * Being a WpObject subclass, the settings inherits WpObject's activation * system. @@ -33,9 +33,6 @@ struct _WpSettings WpProperties *settings; - /* element-type: Rule* */ - GPtrArray *rules; - /* element-type: Callback* */ GPtrArray *callbacks; @@ -43,20 +40,6 @@ struct _WpSettings WpObjectManager *metadata_om; }; -typedef struct -{ - gchar *rule; - /* element-type: Match* */ - GPtrArray *matches; -} Rule; - -typedef struct -{ - /* element-type: WpObjectInterest* */ - GPtrArray *interests; - WpProperties *actions; -} Match; - typedef struct { GClosure *closure; @@ -185,159 +168,6 @@ wp_settings_get (WpSettings *self, const gchar *setting) return value ? wp_spa_json_new_from_string (value) : NULL; } -/*! - * \brief Safely parses a boolean setting, using the fallback value if the - * setting does not exist, or the setting cannot be parsed. A warning is also - * logged when the setting cannot be parsed. - * - * \ingroup wpsettings - * \param self the settings object - * \param setting name of the setting - * \param value fallback value to use in case of error - * \returns The value of the setting, or the fallback value in case of error - */ -gboolean -wp_settings_parse_boolean_safe (WpSettings *self, const gchar *setting, - gboolean value) -{ - g_autoptr (WpSpaJson) json = wp_settings_get(self, setting); - gboolean res = value; - if (json && !wp_spa_json_parse_boolean (json, &res)) - wp_warning_object (self, "Could not parse setting '%s' as boolean", - setting); - return res; -} - -/*! - * \brief Safely parses an integer setting, using the fallback value if the - * setting does not exist, or the setting cannot be parsed. A warning is also - * logged when the setting cannot be parsed. - * - * \ingroup wpsettings - * \param self the settings object - * \param setting name of the setting - * \param value fallback value to use in case of error - * \returns The value of the setting, or the fallback value in case of error - */ -gint -wp_settings_parse_int_safe (WpSettings *self, const gchar *setting, gint value) -{ - g_autoptr (WpSpaJson) json = wp_settings_get(self, setting); - gint res = value; - if (json && !wp_spa_json_parse_int (json, &res)) - wp_warning_object (self, "Could not parse setting '%s' as int", setting); - return res; -} - -/*! - * \brief Safely parses a float setting, using the fallback value if the - * setting does not exist, or the setting cannot be parsed. A warning is also - * logged when the setting cannot be parsed. - * - * \ingroup wpsettings - * \param self the settings object - * \param setting name of the setting - * \param value fallback value to use in case of error - * \returns The value of the setting, or the fallback value in case of error - */ -float -wp_settings_parse_float_safe (WpSettings *self, const gchar *setting, - float value) -{ - g_autoptr (WpSpaJson) json = wp_settings_get(self, setting); - float res = value; - if (json && !wp_spa_json_parse_float (json, &res)) - wp_warning_object (self, "Could not parse setting '%s' as float", setting); - return res; -} - -/*! - * \brief Safely parses a string setting, using the fallback value if the - * setting does not exist, or the setting cannot be parsed. A warning is also - * logged when the setting cannot be parsed. - * - * \ingroup wpsettings - * \param self the settings object - * \param setting name of the setting - * \param value fallback value to use in case of error - * \returns (transfer full): The value of the setting, or the fallback value in - * case of error - */ -gchar * -wp_settings_parse_string_safe (WpSettings *self, const gchar *setting, - const gchar *value) -{ - g_autoptr (WpSpaJson) json = wp_settings_get(self, setting); - if (json) { - gchar *res = wp_spa_json_parse_string (json); - if (res) - return res; - else - wp_warning_object (self, "Could not parse setting '%s' as string", - setting); - } - return g_strdup (value); -} - -/*! - * \brief Applies the rules and returns the applied properties. - * - * This function applies the rules on the client properties and if - * there is a match, it returns TRUE and also copies the applied properties. - * - * \ingroup wpsettings - * \param self the settings object - * \param rule name of the rule; this will match with the section mentioned - * in the conf file. - * \param client_props (transfer none)(inout): client properties array; these - * properties are inputs on which the rules are applied. - * \param applied_props (transfer none)(nullable)(out): the resultant - * actions/properties as a result of the application of rules are copied; - * if this is NULL, properties will be appended to \a client_props instead - * \returns TRUE if there is a match for the client_props and the - * applied properties are returned, FALSE otherwise - */ -gboolean -wp_settings_apply_rule (WpSettings *self, const gchar *rule, - WpProperties *client_props, WpProperties *applied_props) -{ - g_return_val_if_fail (WP_IS_SETTINGS (self), FALSE); - 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", rule); - - for (guint i = 0; i < self->rules->len; i++) { - Rule *r = g_ptr_array_index (self->rules, i); - - if (g_str_equal (rule, r->rule)) { - for (guint j = 0; j < r->matches->len; j++) { - Match *m = g_ptr_array_index (r->matches, j); - - for (guint k = 0; k < m->interests->len; k++) { - WpObjectInterest *interest = g_ptr_array_index (m->interests, k); - - wp_debug_object (self, ". working on interest obj(%p)", interest); - - if (wp_object_interest_matches (interest, client_props)) { - if (applied_props) - wp_properties_add (applied_props, m->actions); - else - wp_properties_add (client_props, m->actions); - - wp_debug_object (self, "match found for rule(%s) with actions" - "(%d)", rule, wp_properties_get_count(m->actions)); - - return TRUE; - } - } - } - } - } - - return FALSE; -} - enum { STEP_LOAD = WP_TRANSITION_STEP_CUSTOM_START, }; @@ -409,240 +239,6 @@ wp_settings_get_instance (WpCore *core, const gchar *metadata_name) return settings; } -static void -match_unref (Match * self) -{ - g_clear_pointer (&self->actions, wp_properties_unref); - g_clear_pointer (&self->interests, g_ptr_array_unref); - g_slice_free (Match, self); -} - -static WpProperties * -parse_actions (const gchar *actions) -{ - g_autoptr (WpSpaJson) o = wp_spa_json_new_from_string (actions); - g_autofree gchar *update_props = NULL; - g_autoptr (WpProperties) a_props = wp_properties_new_empty (); - - wp_debug(".. parsing actions"); - - if (!o || !wp_spa_json_is_object (o)) { - wp_warning ("malformated JSON: actions has to be an object JSON element" - ", skip processing this one"); - return NULL; - } - - if (wp_spa_json_object_get (o, - "update-props", "s", &update_props, - NULL)) { - g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (update_props); - g_autoptr (WpIterator) iter = wp_spa_json_new_iterator (json); - g_auto (GValue) item = G_VALUE_INIT; - - wp_debug (".. update-props=%s", update_props); - - while (wp_iterator_next (iter, &item)) { - WpSpaJson *p = g_value_get_boxed (&item); - g_autofree gchar *prop = wp_spa_json_parse_string (p); - g_autofree gchar *value = NULL; - - g_value_unset (&item); - if (!wp_iterator_next (iter, &item)) - break; - p = g_value_get_boxed (&item); - - value = wp_spa_json_parse_string (p); - g_value_unset (&item); - - if (prop && value) { - wp_debug (".. prop=%s value=%s", prop, value); - wp_properties_set (a_props, prop, value); - } - } - } else { - return NULL; - } - - return g_steal_pointer (&a_props); -} - -static Match * -parse_matches (const gchar *match) -{ - g_autoptr (WpSpaJson) a = wp_spa_json_new_from_string (match); - g_autoptr (WpIterator) a_iter = wp_spa_json_new_iterator (a); - g_auto (GValue) a_item = G_VALUE_INIT; - Match *m = g_slice_new0 (Match); - - g_return_val_if_fail (m, NULL); - - wp_debug(".. parsing match"); - m->interests = g_ptr_array_new_with_free_func - ((GDestroyNotify) wp_object_interest_unref); - - if (!wp_spa_json_is_array (a)) { - wp_warning ("malformated JSON: matches has to be an array JSON element" - ", skip processing this one"); - return NULL; - } - - for (; wp_iterator_next (a_iter, &a_item); g_value_unset (&a_item)) { - g_autoptr (WpObjectInterest) i = wp_object_interest_new_type - (WP_TYPE_PROPERTIES); - WpSpaJson *o = g_value_get_boxed (&a_item); - g_autoptr (WpIterator) o_iter = wp_spa_json_new_iterator (o); - g_auto (GValue) o_item = G_VALUE_INIT; - int count = 0; - - while (wp_iterator_next (o_iter, &o_item)) { - WpSpaJson *p = g_value_get_boxed (&o_item); - if (wp_spa_json_is_container (p)) { - wp_warning ("malformated JSON: misplaced container object, pls check" - " JSON formatting of .conf file, skipping this container"); - continue; - } - g_autofree gchar *isubject = wp_spa_json_parse_string (p); - g_autofree gchar *value = NULL; - gchar *ivalue = NULL; - WpConstraintVerb iverb = WP_CONSTRAINT_VERB_EQUALS; - - g_value_unset (&o_item); - if (!wp_iterator_next (o_iter, &o_item)) - break; - p = g_value_get_boxed (&o_item); - - ivalue = value = wp_spa_json_parse_string (p); - g_value_unset (&o_item); - - if (value[0] == '~') { - iverb = WP_CONSTRAINT_VERB_MATCHES; - ivalue = value+1; - } - if (isubject && ivalue) { - wp_object_interest_add_constraint (i, WP_CONSTRAINT_TYPE_PW_PROPERTY, - isubject, iverb, g_variant_new_string(ivalue)); - count++; - wp_debug (".. subject=%s verb=%d value=%s of interest obj=%p", - isubject, iverb, ivalue, i); - } - } - wp_debug (".. loaded interest obj(%p) with (%d) constraints", i, count); - g_ptr_array_add (m->interests, g_steal_pointer(&i)); - } - return m; -} - -static Rule * -parse_rule (const gchar *rule, const gchar *value) -{ - g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (value); - g_autoptr (WpIterator) iter = wp_spa_json_new_iterator (json); - g_auto (GValue) item = G_VALUE_INIT; - Rule *r = g_slice_new0 (Rule); - - g_return_val_if_fail (r, NULL); - - r->rule = g_strdup (rule); - - wp_debug (". parsing rule(%s)", r->rule); - r->matches = g_ptr_array_new_with_free_func - ((GDestroyNotify) match_unref); - - for (; wp_iterator_next (iter, &item); g_value_unset (&item)) { - WpSpaJson *o = g_value_get_boxed (&item); - g_autofree gchar *match = NULL; - g_autofree gchar *actions = NULL; - Match *m = NULL; - - if (!o || !wp_spa_json_is_object (o)) { - wp_warning ("malformated JSON: rule has to be an object JSON element" - ", skip processing this one"); - continue; - } - - if (!wp_spa_json_object_get (o, - "matches", "s", &match, - "actions", "s", &actions, - NULL)) - continue; - - m = parse_matches (match); - g_ptr_array_add (r->matches, m); - wp_debug (". loaded (%d) interest objects for this match for rule(%s)", - m->interests->len, r->rule); - - m->actions = parse_actions (actions); - wp_debug (". loaded (%d) actions for this match for rule(%s)", - wp_properties_get_count (m->actions), r->rule); - } - - return r; -} - -static gboolean -is_rule (WpSpaJson *json) -{ - /* rule is an array and starts with an object */ - if (wp_spa_json_is_array (json)) { - g_autoptr (WpIterator) iter = wp_spa_json_new_iterator (json); - g_auto (GValue) item = G_VALUE_INIT; - - if (wp_iterator_next (iter, &item)) { - WpSpaJson *o = g_value_get_boxed (&item); - if (o && wp_spa_json_is_object (o)) - return TRUE; - } - } - return FALSE; -} - -static Rule * -find_rule (WpSettings *self, const gchar *name) -{ - for (guint i = 0; i < self->rules->len; i++) { - Rule *r = g_ptr_array_index (self->rules, i); - if (g_str_equal (r->rule, name)) - return r; - } - return NULL; -} - -static void -rule_unref (Rule * self) -{ - g_clear_pointer (&self->rule, g_free); - g_clear_pointer (&self->matches, g_ptr_array_unref); - g_slice_free (Rule, self); -} - -static void -parse_setting (const gchar *setting, const gchar *value, WpSettings *self) -{ - g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (value); - - if (is_rule (json)) { - Rule *r = find_rule (self, setting); - if (r) { - /* append new matches to existing rule */ - Rule *new_r = parse_rule (setting, value); - if (new_r) { - for (guint i = 0; i < new_r->matches->len; i++) { - Match *m = g_ptr_array_index (new_r->matches, i); - g_ptr_array_add (r->matches, m); - } - rule_unref (new_r); - } - } else { - r = parse_rule (setting, value); - g_ptr_array_add (self->rules, r); - } - wp_debug_object (self, "added (%d) matches for rule (%s)", r->matches->len, - r->rule); - } else { - wp_properties_set (self->settings, setting, value); - } -} - static void on_metadata_changed (WpMetadata *m, guint32 subject, const gchar *setting, const gchar *type, const gchar *new_value, gpointer d) @@ -704,16 +300,15 @@ on_metadata_added (WpObjectManager *om, WpMetadata *m, gpointer d) g_signal_connect_object (m, "changed", G_CALLBACK (on_metadata_changed), self, 0); - /* traverse through all settings and rules */ + /* traverse through all settings */ for (; wp_iterator_next (it, &val); g_value_unset (&val)) { const gchar *setting, *value; wp_metadata_iterator_item_extract (&val, NULL, &setting, NULL, &value); - parse_setting (setting, value, self); + wp_properties_set (self->settings, setting, value); } - wp_info_object (self, "loaded %d settings and %d rules from metadata \"%s\"", + wp_info_object (self, "loaded %d settings and from metadata \"%s\"", wp_properties_get_count (self->settings), - self->rules->len, self->metadata_name); wp_object_update_features (WP_OBJECT (self), WP_SETTINGS_LOADED, 0); @@ -739,8 +334,6 @@ wp_settings_activate_execute_step (WpObject * object, case STEP_LOAD: { self->settings = wp_properties_new_empty (); - self->rules = g_ptr_array_new_with_free_func ((GDestroyNotify) rule_unref); - self->callbacks = g_ptr_array_new_with_free_func ((GDestroyNotify) callback_unref); @@ -773,7 +366,6 @@ wp_settings_deactivate (WpObject * object, WpObjectFeatures features) wp_debug_object (self, "%s", self->metadata_name); g_free (self->metadata_name); g_clear_object (&self->metadata_om); - g_clear_pointer (&self->rules, g_ptr_array_unref); g_clear_pointer (&self->callbacks, g_ptr_array_unref); g_clear_pointer (&self->settings, wp_properties_unref); diff --git a/lib/wp/settings.h b/lib/wp/settings.h index b76f908f..9ce3af5e 100644 --- a/lib/wp/settings.h +++ b/lib/wp/settings.h @@ -64,26 +64,6 @@ gboolean wp_settings_unsubscribe (WpSettings *self, WP_API WpSpaJson * wp_settings_get (WpSettings *self, const gchar *setting); -WP_API -gboolean wp_settings_parse_boolean_safe (WpSettings *self, const gchar *setting, - gboolean value); - -WP_API -gint wp_settings_parse_int_safe (WpSettings *self, const gchar *setting, - gint value); - -WP_API -float wp_settings_parse_float_safe (WpSettings *self, const gchar *setting, - float value); - -WP_API -gchar * wp_settings_parse_string_safe (WpSettings *self, const gchar *setting, - const gchar *value); - -WP_API -gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule, - WpProperties *client_props, WpProperties *applied_props); - G_END_DECLS #endif diff --git a/modules/module-lua-scripting/api/api.c b/modules/module-lua-scripting/api/api.c index f7774eab..f78ef7c1 100644 --- a/modules/module-lua-scripting/api/api.c +++ b/modules/module-lua-scripting/api/api.c @@ -1659,157 +1659,6 @@ settings_get (lua_State *L) return 1; } -static int -settings_parse_boolean_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - const gboolean v = lua_toboolean (L, 2) ? TRUE : FALSE; - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - if (s) - lua_pushboolean (L, wp_settings_parse_boolean_safe (s, setting, v)); - else - lua_pushboolean (L, v); - return 1; -} - -static int -settings_parse_int_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - const gint v = luaL_checkinteger (L, 2); - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - if (s) - lua_pushinteger (L, wp_settings_parse_int_safe (s, setting, v)); - else - lua_pushinteger (L, v); - return 1; -} - -static int -settings_parse_float_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - const float v = lua_tonumber (L, 2); - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - if (s) - lua_pushnumber (L, wp_settings_parse_float_safe (s, setting, v)); - else - lua_pushnumber (L, v); - return 1; -} - -static int -settings_parse_string_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - const char *v = luaL_checkstring (L, 2); - g_autofree gchar *res = NULL; - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - res = s ? wp_settings_parse_string_safe (s, setting, v) : g_strdup (v); - lua_pushstring (L, res); - return 1; -} - -static int -settings_parse_array_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - g_autoptr (WpSpaJson) json_default = NULL; - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - if (lua_isuserdata (L, 2)) { - WpSpaJson *v = wplua_checkboxed (L, 2, WP_TYPE_SPA_JSON); - if (v && wp_spa_json_is_array (v)) - json_default = wp_spa_json_ref (v); - } - if (!json_default) { - wp_warning ("Using empty array for setting '%s' as fallback value isn't " - "a JSON array", setting); - json_default = wp_spa_json_new_array (NULL, NULL); - } - - if (s) { - g_autoptr (WpSpaJson) j = wp_settings_get (s, setting); - if (j) { - if (wp_spa_json_is_array (j)) { - push_luajson (L, j); - return 1; - } else { - wp_warning ("Ignoring setting '%s' as it isn't a JSON array", setting); - } - } - } - - push_luajson (L, json_default); - return 1; -} - -static int -settings_parse_object_safe (lua_State *L) -{ - const char *setting = luaL_checkstring (L, 1); - g_autoptr (WpSpaJson) json_default = NULL; - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - if (lua_isuserdata (L, 2)) { - WpSpaJson *v = wplua_checkboxed (L, 2, WP_TYPE_SPA_JSON); - if (v && wp_spa_json_is_object (v)) - json_default = wp_spa_json_ref (v); - } - if (!json_default) { - wp_warning ("Using empty object for setting '%s' as fallback value isn't " - "a JSON object", setting); - json_default = wp_spa_json_new_array (NULL, NULL); - } - - if (s) { - g_autoptr (WpSpaJson) j = wp_settings_get (s, setting); - if (j) { - if (wp_spa_json_is_object (j)) { - push_luajson (L, j); - return 1; - } else { - wp_warning ("Ignoring setting '%s' as it isn't a JSON object", setting); - } - } - } - - push_luajson (L, json_default); - return 1; -} - -static int -settings_apply_rule (lua_State *L) -{ - const char *r = luaL_checkstring (L, 1); - g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), - "sm-settings"); - - g_autoptr (WpProperties) cp = wplua_table_to_properties (L, 2); - g_autoptr (WpProperties) ap = wp_properties_new_empty (); - - - if (s) { - gboolean value = wp_settings_apply_rule (s, r, cp, ap); - lua_pushboolean (L, value); - wplua_properties_to_table (L, ap); - return 2; - } - - lua_pushnil (L); - return 1; -} - static int settings_subscribe (lua_State *L) { @@ -1828,7 +1677,6 @@ settings_subscribe (lua_State *L) return 1; } - static int settings_unsubscribe (lua_State *L) { @@ -1846,13 +1694,6 @@ settings_unsubscribe (lua_State *L) static const luaL_Reg settings_methods[] = { { "get", settings_get }, - { "parse_boolean_safe", settings_parse_boolean_safe }, - { "parse_int_safe", settings_parse_int_safe }, - { "parse_float_safe", settings_parse_float_safe }, - { "parse_string_safe", settings_parse_string_safe }, - { "parse_array_safe", settings_parse_array_safe }, - { "parse_object_safe", settings_parse_object_safe }, - { "apply_rule", settings_apply_rule }, { "subscribe", settings_subscribe }, { "unsubscribe", settings_unsubscribe }, { NULL, NULL } diff --git a/src/config/wireplumber.conf.d/access.conf b/src/config/wireplumber.conf.d/access.conf index d1424f2b..719f32bf 100644 --- a/src/config/wireplumber.conf.d/access.conf +++ b/src/config/wireplumber.conf.d/access.conf @@ -3,46 +3,41 @@ wireplumber.settings = { ## Enables flatpak portal # access-enable-flatpak-portal = true - - ## The list of access rules - access.rules = [ - ## The following are the default rules applied if none overrides them. - # { - # matches = [ - # { - # pipewire.access = "flatpak" - # media.category = "Manager" - # } - # ] - # actions = { - # update-props = { - # default_permissions = "all", - # } - # } - # } - # { - # matches = [ - # { - # pipewire.access = "flatpak" - # } - # ] - # actions = { - # update-props = { - # default_permissions = "rx" - # } - # } - # } - # { - # matches = [ - # { - # pipewire.access = "restricted" - # } - # ] - # actions = { - # update-props = { - # default_permissions = "rx" - # } - # } - # } - ] } + +access.rules = [ + ## The list of access rules + + ## The following are the default rules applied if none overrides them. + # { + # matches = [ + # { + # pipewire.access = "flatpak" + # media.category = "Manager" + # } + # ] + # update-props = { + # default_permissions = "all", + # } + # } + # { + # matches = [ + # { + # pipewire.access = "flatpak" + # } + # ] + # update-props = { + # default_permissions = "rx" + # } + # } + # { + # matches = [ + # { + # pipewire.access = "restricted" + # } + # ] + # update-props = { + # default_permissions = "rx" + # } + # } +] diff --git a/src/config/wireplumber.conf.d/alsa.conf b/src/config/wireplumber.conf.d/alsa.conf index ff9c087d..2728b417 100644 --- a/src/config/wireplumber.conf.d/alsa.conf +++ b/src/config/wireplumber.conf.d/alsa.conf @@ -21,153 +21,152 @@ wireplumber.settings = { ## not used by the session manager, in order to be able to ## connect to the real JACK server. # monitor.alsa.jack-device = false +} +monitor.alsa.properties = { ## The properties used when constructing the 'api.alsa.enum.udev' plugin - # monitor.alsa.properties = {} +} +monitor.alsa.midi.node-properties = { + ## MIDI bridge node properties + + ## Name set for the node with ALSA MIDI ports + node.name = "Midi-Bridge" + + ## Removes longname/number from MIDI port names + api.alsa.disable-longname = true +} + +monitor.alsa.vm.node.defaults = { ## These properties override node defaults when running in a virtual machine. ## The rules below still override those. - # monitor.alsa.vm.node.defaults = { - # api.alsa.period-size = 256 - # api.alsa.headroom = 8192 - # } - ## MIDI bridge node properties - # monitor.alsa.midi.node-properties = { - # ## Name set for the node with ALSA MIDI ports - # node.name = "Midi-Bridge" - # ## Removes longname/number from MIDI port names - # api.alsa.disable-longname = true - # } - - ## The list of monitor rules - monitor.alsa.rules = [ - ## The following are the default rules applied if none overrides them. - # { - # matches = [ - # { - # device.name = "~alsa_card.*" - # } - # ] - # actions = { - # update-props = { - # api.alsa.use-acp = true - # api.acp.auto-port = false - # } - # } - # } - - ## This rule example allows changing properties on all ALSA devices. - # { - # matches = [ - # { - # ## This matches all cards. - # device.name = "~alsa_card.*" - # } - # ] - # actions = { - # update-props = { - # ## Use ALSA-Card-Profile devices. They use UCM or the profile - # ## configuration to configure the device and mixer settings. - # api.alsa.use-acp = false - # - # ## Use UCM instead of profile when available. Can be - # ## disabled to skip trying to use the UCM profile. - # api.alsa.use-ucm = false - # - # ## Don't use the hardware mixer for volume control. It - # ## will only use software volume. The mixer is still used - # ## to mute unused paths based on the selected port. - # api.alsa.soft-mixer = false - # - # ## Ignore decibel settings of the driver. Can be used to - # ## work around buggy drivers that report wrong values. - # api.alsa.ignore-dB = false - # - # ## The profile set to use for the device. Usually this is - # ## "default.conf" but can be changed with a udev rule or here. - # device.profile-set = "profileset-name" - # - # ## The default active profile. Is by default set to "Off". - # device.profile = "default profile name" - # - # ## Automatically select the best profile. This is the - # ## highest priority available profile. This is disabled - # ## here and instead implemented in the session manager - # ## where it can save and load previous preferences. - # api.acp.auto-profile = false - # - # ## Automatically switch to the highest priority available port. - # ## This is disabled here and implemented in the session manager instead. - # api.acp.auto-port = true - # - # ## Other properties can be set here. - # device.nick = "My Device" - # - # ## Whether to disable the device or not - # device.disabled = false - # } - # } - # } - - ## This rule example allows changing properties on all ALSA nodes. - # { - # matches = [ - # { - # ## Matches all sources. - # node.name = "~alsa_input.*" - # } - # { - # ## Matches all sinks. - # node.name = "~alsa_output.*" - # } - # ] - # actions = { - # update-props = { - # node.nick = "My Node" - # node.description = "My Node Description" - # priority.driver = 100 - # priority.session = 100 - # node.pause-on-idle = false - # monitor.channel-volumes = false - # resample.quality = 4 - # resample.disable = false - # channelmix.normalize = false - # channelmix.mix-lfe = false - # channelmix.upmix = true - # - # ## only "psd", "none" or "simple" values are accepted - # channelmix.upmix-method = "psd" - # - # channelmix.lfe-cutoff = 150 - # channelmix.fc-cutoff = 12000 - # channelmix.rear-delay = 12.0 - # channelmix.stereo-widen = 0.0 - # channelmix.hilbert-taps = 0 - # channelmix.disable = false - # dither.noise = 0 - # dither.method = "none" - # audio.channels = 2 - # audio.format = "S16LE" - # audio.rate = 44100 - # audio.allowed-rates = "32000,96000" - # audio.position = "FLFR" - # api.alsa.period-size = 1024 - # api.alsa.period-num = 2 - # api.alsa.headroom = 0 - # api.alsa.start-delay = 0 - # api.alsa.disable-mmap = false - # api.alsa.disable-batch = false - # api.alsa.use-chmap = false - # api.alsa.multirate = true - # latency.internal.rate = 0 - # latency.internal.ns = 0 - # clock.name = "api.alsa.0" - # - # ## 0 disables suspend - # session.suspend-timeout-seconds = 5 - # } - # } - # } - ] + api.alsa.period-size = 256 + api.alsa.headroom = 8192 } + +monitor.alsa.rules = [ + ## The list of monitor rules + + ## The following are the default rules applied if none overrides them. + # { + # matches = [ + # { + # device.name = "~alsa_card.*" + # } + # ] + # update-props = { + # api.alsa.use-acp = true + # api.acp.auto-port = false + # } + # } + + ## This rule example allows changing properties on all ALSA devices. + # { + # matches = [ + # { + # ## This matches all cards. + # device.name = "~alsa_card.*" + # } + # ] + # update-props = { + # ## Use ALSA-Card-Profile devices. They use UCM or the profile + # ## configuration to configure the device and mixer settings. + # api.alsa.use-acp = false + # + # ## Use UCM instead of profile when available. Can be + # ## disabled to skip trying to use the UCM profile. + # api.alsa.use-ucm = false + # + # ## Don't use the hardware mixer for volume control. It + # ## will only use software volume. The mixer is still used + # ## to mute unused paths based on the selected port. + # api.alsa.soft-mixer = false + # + # ## Ignore decibel settings of the driver. Can be used to + # ## work around buggy drivers that report wrong values. + # api.alsa.ignore-dB = false + # + # ## The profile set to use for the device. Usually this is + # ## "default.conf" but can be changed with a udev rule or here. + # device.profile-set = "profileset-name" + # + # ## The default active profile. Is by default set to "Off". + # device.profile = "default profile name" + # + # ## Automatically select the best profile. This is the + # ## highest priority available profile. This is disabled + # ## here and instead implemented in the session manager + # ## where it can save and load previous preferences. + # api.acp.auto-profile = false + # + # ## Automatically switch to the highest priority available port. + # ## This is disabled here and implemented in the session manager instead. + # api.acp.auto-port = true + # + # ## Other properties can be set here. + # device.nick = "My Device" + # + # ## Whether to disable the device or not + # device.disabled = false + # } + # } + + ## This rule example allows changing properties on all ALSA nodes. + # { + # matches = [ + # { + # ## Matches all sources. + # node.name = "~alsa_input.*" + # } + # { + # ## Matches all sinks. + # node.name = "~alsa_output.*" + # } + # ] + # update-props = { + # node.nick = "My Node" + # node.description = "My Node Description" + # priority.driver = 100 + # priority.session = 100 + # node.pause-on-idle = false + # monitor.channel-volumes = false + # resample.quality = 4 + # resample.disable = false + # channelmix.normalize = false + # channelmix.mix-lfe = false + # channelmix.upmix = true + # + # ## only "psd", "none" or "simple" values are accepted + # channelmix.upmix-method = "psd" + # + # channelmix.lfe-cutoff = 150 + # channelmix.fc-cutoff = 12000 + # channelmix.rear-delay = 12.0 + # channelmix.stereo-widen = 0.0 + # channelmix.hilbert-taps = 0 + # channelmix.disable = false + # dither.noise = 0 + # dither.method = "none" + # audio.channels = 2 + # audio.format = "S16LE" + # audio.rate = 44100 + # audio.allowed-rates = "32000,96000" + # audio.position = "FLFR" + # api.alsa.period-size = 1024 + # api.alsa.period-num = 2 + # api.alsa.headroom = 0 + # api.alsa.start-delay = 0 + # api.alsa.disable-mmap = false + # api.alsa.disable-batch = false + # api.alsa.use-chmap = false + # api.alsa.multirate = true + # latency.internal.rate = 0 + # latency.internal.ns = 0 + # clock.name = "api.alsa.0" + # + # ## 0 disables suspend + # session.suspend-timeout-seconds = 5 + # } + # } +] diff --git a/src/config/wireplumber.conf.d/bluetooth.conf b/src/config/wireplumber.conf.d/bluetooth.conf index 9fc5c73d..55ab5f3a 100644 --- a/src/config/wireplumber.conf.d/bluetooth.conf +++ b/src/config/wireplumber.conf.d/bluetooth.conf @@ -8,186 +8,187 @@ wireplumber.settings = { ## This requires access to the D-Bus user session; disable if you are running ## a system-wide instance of wireplumber. # monitor.bluetooth.enable-logind = true +} +monitor.bluetooth.properties = { ## The properties used when constructing the 'api.bluez5.enum.dbus' plugin - # monitor.bluetooth.properties = { - # ## Whether to support connection info or not - # api.bluez5.connection-info = true - # ## These features do not work on all headsets, so they are enabled - # ## by default based on the hardware database. They can also be - # ## forced on/off for all devices by the following options: - # bluez5.enable-sbc-xq = true - # bluez5.enable-msbc = true - # bluez5.enable-hw-volume = true + ## Whether to support connection info or not + api.bluez5.connection-info = true - # ## Enabled roles (default: [ a2dp_sink a2dp_source bap_sink bap_source hfp_hf hfp_ag ]) - # ## - # ## Currently some headsets (Sony WH-1000XM3) are not working with - # ## both hsp_ag and hfp_ag enabled, so by default we enable only HFP. - # ## - # ## Supported roles: hsp_hs (HSP Headset), - # ## hsp_ag (HSP Audio Gateway), - # ## hfp_hf (HFP Hands-Free), - # ## hfp_ag (HFP Audio Gateway) - # ## a2dp_sink (A2DP Audio Sink) - # ## a2dp_source (A2DP Audio Source) - # ## bap_sink (LE Audio Basic Audio Profile Sink) - # ## bap_source (LE Audio Basic Audio Profile Source) - # # bluez5.roles = "[ a2dp_sink a2dp_source bap_sink bap_source hsp_hs hsp_ag hfp_hf hfp_ag ]" + ## Enabled roles (default: [ a2dp_sink a2dp_source bap_sink bap_source hfp_hf hfp_ag ]) + ## + ## Currently some headsets (Sony WH-1000XM3) are not working with + ## both hsp_ag and hfp_ag enabled, so by default we enable only HFP. + ## + ## Supported roles: hsp_hs (HSP Headset), + ## hsp_ag (HSP Audio Gateway), + ## hfp_hf (HFP Hands-Free), + ## hfp_ag (HFP Audio Gateway) + ## a2dp_sink (A2DP Audio Sink) + ## a2dp_source (A2DP Audio Source) + ## bap_sink (LE Audio Basic Audio Profile Sink) + ## bap_source (LE Audio Basic Audio Profile Source) + # bluez5.roles = "[ a2dp_sink a2dp_source bap_sink bap_source hsp_hs hsp_ag hfp_hf hfp_ag ]" - # ## Enabled A2DP codecs (default: all). - # bluez5.codecs = "[ sbc sbc_xq aac ldac aptx aptx_hd aptx_ll aptx_ll_duplex faststream faststream_duplex ]" + ## Enabled A2DP codecs (default: all). + # bluez5.codecs = "[ sbc sbc_xq aac ldac aptx aptx_hd aptx_ll aptx_ll_duplex faststream faststream_duplex ]" - # ## HFP/HSP backend (default: native). - # ## Available values: any, none, hsphfpd, ofono, native - # bluez5.hfphsp-backend = "native" + ## These features do not work on all headsets, so they are enabled + ## by default based on the hardware database. They can also be + ## forced on/off for all devices by the following options: + # bluez5.enable-sbc-xq = true + # bluez5.enable-msbc = true + # bluez5.enable-hw-volume = true - # ## HFP/HSP native backend modem (default: none). - # ## Available values: none, any or the modem device string as found in - # ## 'Device' property of org.freedesktop.ModemManager1.Modem interface - # bluez5.hfphsp-backend-native-modem = "none" + ## HFP/HSP backend (default: native). + ## Available values: any, none, hsphfpd, ofono, native + # bluez5.hfphsp-backend = "native" - # ## HFP/HSP hardware offload SCO support (default: false). - # bluez5.hw-offload-sco = false + ## HFP/HSP native backend modem (default: none). + ## Available values: none, any or the modem device string as found in + ## 'Device' property of org.freedesktop.ModemManager1.Modem interface + # bluez5.hfphsp-backend-native-modem = "none" - # ## Properties for the A2DP codec configuration - # bluez5.default.rate = 48000 - # bluez5.default.channels = 2 + ## HFP/HSP hardware offload SCO support (default: false). + # bluez5.hw-offload-sco = false - # ## Register dummy AVRCP player, required for AVRCP volume function. - # ## Disable if you are running mpris-proxy or equivalent. - # bluez5.dummy-avrcp-player = true + ## Properties for the A2DP codec configuration + # bluez5.default.rate = 48000 + # bluez5.default.channels = 2 - # ## Opus Pro Audio mode settings - # bluez5.a2dp.opus.pro.channels = 3 - # bluez5.a2dp.opus.pro.coupled-streams = 1 - # bluez5.a2dp.opus.pro.locations = "FL,FR,LFE" - # bluez5.a2dp.opus.pro.max-bitrate = 600000 - # bluez5.a2dp.opus.pro.frame-dms = 50 - # bluez5.a2dp.opus.pro.bidi.channels = 1 - # bluez5.a2dp.opus.pro.bidi.coupled-streams = 0 - # bluez5.a2dp.opus.pro.bidi.locations = "FC" - # bluez5.a2dp.opus.pro.bidi.max-bitrate = 160000 - # bluez5.a2dp.opus.pro.bidi.frame-dms = 400 - # } + ## Register dummy AVRCP player, required for AVRCP volume function. + ## Disable if you are running mpris-proxy or equivalent. + # bluez5.dummy-avrcp-player = true + ## Opus Pro Audio mode settings + # bluez5.a2dp.opus.pro.channels = 3 + # bluez5.a2dp.opus.pro.coupled-streams = 1 + # bluez5.a2dp.opus.pro.locations = "FL,FR,LFE" + # bluez5.a2dp.opus.pro.max-bitrate = 600000 + # bluez5.a2dp.opus.pro.frame-dms = 50 + # bluez5.a2dp.opus.pro.bidi.channels = 1 + # bluez5.a2dp.opus.pro.bidi.coupled-streams = 0 + # bluez5.a2dp.opus.pro.bidi.locations = "FC" + # bluez5.a2dp.opus.pro.bidi.max-bitrate = 160000 + # bluez5.a2dp.opus.pro.bidi.frame-dms = 400 +} + +monitor.bluetooth-midi.properties = { ## The properties used when constructing the 'api.bluez5.midi.enum' plugin - monitor.bluetooth-midi.properties = {} +} +monitor.bluetooth-midi.servers = [ ## List of MIDI server node names. Each node name given will create a new instance ## of a BLE MIDI service. Typical BLE MIDI instruments have on service instance, ## so adding more than one here may confuse some clients. The node property matching ## rules below apply also to these servers. - monitor.bluetooth-midi.servers = [ "bluez_midi.server" ] + "bluez_midi.server" +] + +monitor.bluetooth.rules = [ ## The list of monitor rules - monitor.bluetooth = [ - ## The following are the default rules applied if none overrides them. - # { - # matches = [ - # { - # device.name = "~bluez_card.*" - # } - # ] - # actions = { - # update-props = { - # bluez5.auto-connect = "[ hfp_hf hsp_hs a2dp_sink ]" - # } - # } - # } - ## This rule example allows changing properties on all Bluetooth devices. - # { - # matches = [ - # { - # ## This matches all cards. - # device.name = "~bluez_card.*" - # } - # ] - # actions = { - # update-props = { - # ## Auto-connect device profiles on start up or when only partial - # ## profiles have connected. Disabled by default if the property - # ## is not specified. - # bluez5.auto-connect = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]" - # - # ## Hardware volume control (default: [ hfp_ag hsp_ag a2dp_source ]) - # bluez5.hw-volume = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]" - # - # ## LDAC encoding quality - # ## Available values: auto (Adaptive Bitrate, default) - # ## hq (High Quality, 990/909kbps) - # ## sq (Standard Quality, 660/606kbps) - # ## mq (Mobile use Quality, 330/303kbps) - # bluez5.a2dp.ldac.quality = "auto" - # - # ## AAC variable bitrate mode - # ## Available values: 0 (cbr, default), 1-5 (quality level) - # bluez5.a2dp.aac.bitratemode = 0 - # - # ## Profile connected first - # ## Available values: a2dp-sink (default), headset-head-unit - # device.profile = "a2dp-sink" - # - # ## Opus Pro Audio encoding mode: audio, voip, lowdelay - # bluez5.a2dp.opus.pro.application = "audio" - # bluez5.a2dp.opus.pro.bidi.application = "audio" - # } - # } - # } + ## The following are the default rules applied if none overrides them. + # { + # matches = [ + # { + # device.name = "~bluez_card.*" + # } + # ] + # update-props = { + # bluez5.auto-connect = "[ hfp_hf hsp_hs a2dp_sink ]" + # } + # } - ## This rule example allows changing properties on all Bluetooth nodes. - # { - # matches = [ - # { - # ## Matches all sources. - # node.name = "~bluez_input.*" - # } - # { - # ## Matches all sinks. - # node.name = "~bluez_output.*" - # } - # ] - # actions = { - # update-props = { - # node.nick = "My Node" - # priority.driver = 100 - # priority.session = 100 - # node.pause-on-idle = false - # resample.quality = 4 - # channelmix.normalize = false - # channelmix.mix-lfe = false - # session.suspend-timeout-seconds = 5 - # monitor.channel-volumes = false - # - # ## Media source role, "input" or "playback" - # ## Defaults to "playback", playing stream to speakers - # ## Set to "input" to use as an input for apps - # bluez5.media-source-role = "input" - # } - # } - # } - ] + ## This rule example allows changing properties on all Bluetooth devices. + # { + # matches = [ + # { + # ## This matches all cards. + # device.name = "~bluez_card.*" + # } + # ] + # update-props = { + # ## Auto-connect device profiles on start up or when only partial + # ## profiles have connected. Disabled by default if the property + # ## is not specified. + # bluez5.auto-connect = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]" + # + # ## Hardware volume control (default: [ hfp_ag hsp_ag a2dp_source ]) + # bluez5.hw-volume = "[ hfp_hf hsp_hs a2dp_sink hfp_ag hsp_ag a2dp_source ]" + # + # ## LDAC encoding quality + # ## Available values: auto (Adaptive Bitrate, default) + # ## hq (High Quality, 990/909kbps) + # ## sq (Standard Quality, 660/606kbps) + # ## mq (Mobile use Quality, 330/303kbps) + # bluez5.a2dp.ldac.quality = "auto" + # + # ## AAC variable bitrate mode + # ## Available values: 0 (cbr, default), 1-5 (quality level) + # bluez5.a2dp.aac.bitratemode = 0 + # + # ## Profile connected first + # ## Available values: a2dp-sink (default), headset-head-unit + # device.profile = "a2dp-sink" + # + # ## Opus Pro Audio encoding mode: audio, voip, lowdelay + # bluez5.a2dp.opus.pro.application = "audio" + # bluez5.a2dp.opus.pro.bidi.application = "audio" + # } + # } + ## This rule example allows changing properties on all Bluetooth nodes. + # { + # matches = [ + # { + # ## Matches all sources. + # node.name = "~bluez_input.*" + # } + # { + # ## Matches all sinks. + # node.name = "~bluez_output.*" + # } + # ] + # update-props = { + # node.nick = "My Node" + # priority.driver = 100 + # priority.session = 100 + # node.pause-on-idle = false + # resample.quality = 4 + # channelmix.normalize = false + # channelmix.mix-lfe = false + # session.suspend-timeout-seconds = 5 + # monitor.channel-volumes = false + # + # ## Media source role, "input" or "playback" + # ## Defaults to "playback", playing stream to speakers + # ## Set to "input" to use as an input for apps + # bluez5.media-source-role = "input" + # } + # } +] + +monitor.bluetooth-midi.rules = [ ## The list of monitor MIDI rules - monitor.bluetooth-midi = [ - ## This rule example allows changing properties on all Bluetooth MIDI nodes. - # { - # matches = { - # { - # ## Matches all nodes. - # { "node.name", "matches", "bluez_midi.*" }, - # }, - # }, - # update-props = { - # node.nick = "My Node" - # priority.driver = 100 - # priority.session = 100 - # node.pause-on-idle = false - # session.suspend-timeout-seconds = 5 - # monitor.channel-volumes = false - # } - # } - ] -} + + ## This rule example allows changing properties on all Bluetooth MIDI nodes. + # { + # matches = { + # { + # ## Matches all nodes. + # { "node.name", "matches", "bluez_midi.*" }, + # }, + # }, + # update-props = { + # node.nick = "My Node" + # priority.driver = 100 + # priority.session = 100 + # node.pause-on-idle = false + # session.suspend-timeout-seconds = 5 + # monitor.channel-volumes = false + # } + # } +] diff --git a/src/config/wireplumber.conf.d/device.conf b/src/config/wireplumber.conf.d/device.conf index 9f8aebba..c50b0afe 100644 --- a/src/config/wireplumber.conf.d/device.conf +++ b/src/config/wireplumber.conf.d/device.conf @@ -23,24 +23,4 @@ wireplumber.settings = { ## Sets the default echo-cancel-source node name to automatically switch to # device.echo-cancel-source-name = "echo-cancel-source" - - ## Sets persistent device profiles that should never be changed, when - ## wireplumber is running, even if a new profile with higher priority becomes - ## available - device.rules = [ - ## The following are the default rules applied if none overrides them. - # { - # matches = [ - # { - # ## Matches all devices - # device.name = "~*" - # } - # ] - # actions = { - # update-props = { - # persistent_profile_names = "off pro-audio" - # } - # } - # } - ] } diff --git a/src/config/wireplumber.conf.d/endpoint.conf b/src/config/wireplumber.conf.d/endpoint.conf index bf8251c9..3d4824b9 100644 --- a/src/config/wireplumber.conf.d/endpoint.conf +++ b/src/config/wireplumber.conf.d/endpoint.conf @@ -1,95 +1,95 @@ ## The WirePlumber endpoint configuration -wireplumber.settings = { +endpoints = { ## The list of endpoints to create - endpoints = { - # endpoint.capture = { - # media.class = "Audio/Source" - # role = "Capture" - # } - # endpoint.multimedia = { - # media.class = "Audio/Sink" - # role = "Multimedia" - # } - # endpoint.speech_low = { - # media.class = "Audio/Sink" - # role = "Speech-Low" - # } - # endpoint.custom_low = { - # media.class = "Audio/Sink" - # role = "Custom-Low" - # } - # endpoint.navigation = { - # media.class = "Audio/Sink" - # role = "Navigation" - # } - # endpoint.speech_high = { - # media.class = "Audio/Sink" - # role = "Speech-High" - # } - # endpoint.custom_high = { - # media.class = "Audio/Sink" - # role = "Custom-High" - # } - # endpoint.communication = { - # media.class = "Audio/Sink" - # role = "Communication" - # } - # endpoint.emergency = { - # media.class = "Audio/Sink" - # role = "Emergency" - # } - } - ## The list of endpoint roles to use - endpoints-roles = { - # Capture = { - # alias = [ "Multimedia", "Music", "Voice", "Capture" ] - # priority = 25 - # action.default = "cork" - # action.capture = "mix" - # media.class = "Audio/Source" - # } - # Multimedia = { - # alias = [ "Movie" "Music" "Game" ] - # priority = 25 - # action.default = "cork" - # } - # Speech-Low = { - # priority = 30 - # action.default = "cork" - # action.Speech-Low = "mix" - # } - # Custom-Low = { - # priority = 35 - # action.default = "cork" - # action.Custom-Low = "mix" - # } - # Navigation = { - # priority = 50 - # action.default = "duck" - # action.Navigation = "mix" - # } - # Speech-High = { - # priority = 60 - # action.default = "cork" - # action.Speech-High = "mix" - # } - # Custom-High = { - # priority = 65 - # action.default = "cork" - # action.Custom-High = "mix" - # } - # Communication = { - # priority = 75 - # action.default = "cork" - # action.Communication = "mix" - # } - # Emergency = { - # alias = [ "Alert" ] - # priority = 99 - # action.default = "cork" - # action.Emergency = "mix" - # } - } + # endpoint.capture = { + # media.class = "Audio/Source" + # role = "Capture" + # } + # endpoint.multimedia = { + # media.class = "Audio/Sink" + # role = "Multimedia" + # } + # endpoint.speech_low = { + # media.class = "Audio/Sink" + # role = "Speech-Low" + # } + # endpoint.custom_low = { + # media.class = "Audio/Sink" + # role = "Custom-Low" + # } + # endpoint.navigation = { + # media.class = "Audio/Sink" + # role = "Navigation" + # } + # endpoint.speech_high = { + # media.class = "Audio/Sink" + # role = "Speech-High" + # } + # endpoint.custom_high = { + # media.class = "Audio/Sink" + # role = "Custom-High" + # } + # endpoint.communication = { + # media.class = "Audio/Sink" + # role = "Communication" + # } + # endpoint.emergency = { + # media.class = "Audio/Sink" + # role = "Emergency" + # } +} + +endpoint-roles = { + ## The list of endpoint roles to use + + # Capture = { + # alias = [ "Multimedia", "Music", "Voice", "Capture" ] + # priority = 25 + # action.default = "cork" + # action.capture = "mix" + # media.class = "Audio/Source" + # } + # Multimedia = { + # alias = [ "Movie" "Music" "Game" ] + # priority = 25 + # action.default = "cork" + # } + # Speech-Low = { + # priority = 30 + # action.default = "cork" + # action.Speech-Low = "mix" + # } + # Custom-Low = { + # priority = 35 + # action.default = "cork" + # action.Custom-Low = "mix" + # } + # Navigation = { + # priority = 50 + # action.default = "duck" + # action.Navigation = "mix" + # } + # Speech-High = { + # priority = 60 + # action.default = "cork" + # action.Speech-High = "mix" + # } + # Custom-High = { + # priority = 65 + # action.default = "cork" + # action.Custom-High = "mix" + # } + # Communication = { + # priority = 75 + # action.default = "cork" + # action.Communication = "mix" + # } + # Emergency = { + # alias = [ "Alert" ] + # priority = 99 + # action.default = "cork" + # action.Emergency = "mix" + # } } diff --git a/src/config/wireplumber.conf.d/libcamera.conf b/src/config/wireplumber.conf.d/libcamera.conf index 6cd93d85..a9ddf679 100644 --- a/src/config/wireplumber.conf.d/libcamera.conf +++ b/src/config/wireplumber.conf.d/libcamera.conf @@ -3,47 +3,45 @@ wireplumber.settings = { ## Enables libcamera monitor # monitor.libcamera.enable = true - - ## The properties used when constructing the 'api.libcamera.enum.manager' plugin - # monitor.libcamera.properties = {} - - ## The list of monitor rules - monitor.libcamera.rules = [ - ## This rule example allows changing properties on all libcamera devices. - # { - # matches = [ - # { - # ## This matches all cards. - # device.name = "~libcamera_device.*" - # } - # ] - # actions = { - # update-props = { - # device.nick = "My Device" - # } - # } - # } - - ## This rule example allows changing properties on all libcamera nodes. - # { - # matches = [ - # { - # ## Matches all sources. - # node.name = "~libcamera_input.*" - # } - # { - # ## Matches all sinks. - # node.name = "~libcamera_output.*" - # } - # ] - # actions = { - # update-props = { - # node.nick = "My Node" - # priority.driver = 100 - # priority.session = 100 - # node.pause-on-idle = false - # } - # } - # } - ] } + +monitor.libcamera.properties = { + ## The properties used when constructing the 'api.libcamera.enum.manager' plugin +} + +monitor.libcamera.rules = [ + ## The list of monitor rules + + ## This rule example allows changing properties on all libcamera devices. + # { + # matches = [ + # { + # ## This matches all cards. + # device.name = "~libcamera_device.*" + # } + # ] + # update-props = { + # device.nick = "My Device" + # } + # } + + ## This rule example allows changing properties on all libcamera nodes. + # { + # matches = [ + # { + # ## Matches all sources. + # node.name = "~libcamera_input.*" + # } + # { + # ## Matches all sinks. + # node.name = "~libcamera_output.*" + # } + # ] + # update-props = { + # node.nick = "My Node" + # priority.driver = 100 + # priority.session = 100 + # node.pause-on-idle = false + # } + # } +] diff --git a/src/config/wireplumber.conf.d/policy.conf b/src/config/wireplumber.conf.d/policy.conf index db486133..18d73123 100644 --- a/src/config/wireplumber.conf.d/policy.conf +++ b/src/config/wireplumber.conf.d/policy.conf @@ -30,10 +30,10 @@ wireplumber.settings = { ## Application names correspond to application.name in stream properties. ## Applications which do not set media.role but which should be considered ## for role based profile switching can be specified here. - # policy.bluetooth.media-role.applications = [ - # "Firefox", "Chromium input", "Google Chrome input", "Brave input", - # "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine", - # "Telegram Desktop", "telegram-desktop", "linphone", "Mumble", - # "WEBRTC VoiceEngine", "Skype" - # ] + policy.bluetooth.media-role.applications = [ + "Firefox", "Chromium input", "Google Chrome input", "Brave input", + "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine", + "Telegram Desktop", "telegram-desktop", "linphone", "Mumble", + "WEBRTC VoiceEngine", "Skype" + ] } diff --git a/src/config/wireplumber.conf.d/stream.conf b/src/config/wireplumber.conf.d/stream.conf index 60910e79..1f7473a4 100644 --- a/src/config/wireplumber.conf.d/stream.conf +++ b/src/config/wireplumber.conf.d/stream.conf @@ -10,22 +10,21 @@ wireplumber.settings = { ## The default channel volume for new streams whose props were never saved ## previously. This is only used if "restore-props" is set to true. # stream.default-channel-volume = 1.0 - - ## The list of stream rules - stream.rules = [ - ## This rule example allows setting properties on the "pw-play" stream. - # { - # matches = [ - # ## Matches all devices - # { application.name = "pw-play" } - # ] - # actions = { - # update-props = { - # state.restore-props = false - # state.restore-target = false - # state.default-channel-volume = 1.0 - # } - # } - # } - ] } + +stream.rules = [ + ## The list of stream rules + + ## This rule example allows setting properties on the "pw-play" stream. + # { + # matches = [ + # ## Matches all devices + # { application.name = "pw-play" } + # ] + # update-props = { + # state.restore-props = false + # state.restore-target = false + # state.default-channel-volume = 1.0 + # } + # } +] diff --git a/src/config/wireplumber.conf.d/v4l2.conf b/src/config/wireplumber.conf.d/v4l2.conf index 38fedd7c..6f4420d0 100644 --- a/src/config/wireplumber.conf.d/v4l2.conf +++ b/src/config/wireplumber.conf.d/v4l2.conf @@ -1,46 +1,42 @@ ## The WirePlumber V4L2 configuration -wireplumber.settings = { +monitor.v4l2.properties = { ## The properties used when constructing the 'api.v4l2.enum.udev' plugin - # monitor.v4l2.properties = {} - - ## The list of monitor rules - monitor.v4l2.rules = [ - ## This rule example allows changing properties on all V4L2 devices. - # { - # matches = [ - # { - # ## This matches all cards. - # device.name = "~v4l2_device.*" - # } - # ] - # actions = { - # update-props = { - # device.nick = "My Device" - # } - # } - # } - - ## This rule example allows changing properties on all V4L2 nodes. - # { - # matches = [ - # { - # ## Matches all sources. - # node.name = "~v4l2_input.*" - # } - # { - # ## Matches all sinks. - # node.name = "~v4l2_output.*" - # } - # ] - # actions = { - # update-props = { - # node.nick = "My Node" - # priority.driver = 100 - # priority.session = 100 - # node.pause-on-idle = false - # } - # } - # } - ] } + +monitor.v4l2.rules = [ + ## The list of monitor rules. + + ## This rule example allows changing properties on all V4L2 devices. + # { + # matches = [ + # { + # ## This matches all cards. + # device.name = "~v4l2_device.*" + # } + # ] + # update-props = { + # device.nick = "My Device" + # } + # } + + ## This rule example allows changing properties on all V4L2 nodes. + # { + # matches = [ + # { + # ## Matches all sources. + # node.name = "~v4l2_input.*" + # } + # { + # ## Matches all sinks. + # node.name = "~v4l2_output.*" + # } + # ] + # update-props = { + # node.nick = "My Node" + # priority.driver = 100 + # priority.session = 100 + # node.pause-on-idle = false + # } + # } +] diff --git a/src/scripts/client/access-default.lua b/src/scripts/client/access-default.lua index 898d44e5..f52b8468 100644 --- a/src/scripts/client/access-default.lua +++ b/src/scripts/client/access-default.lua @@ -19,7 +19,8 @@ function getDefaultPermissions (properties) end function getPermissions (properties) - local matched, mprops = Settings.apply_rule ("access.rules", properties) + local matched, mprops = Conf.apply_rules ("access.rules", + properties) if (matched and mprops["default_permissions"]) then return mprops["default_permissions"] diff --git a/src/scripts/lib/common-utils.lua b/src/scripts/lib/common-utils.lua index ce3b8e4e..541eb168 100644 --- a/src/scripts/lib/common-utils.lua +++ b/src/scripts/lib/common-utils.lua @@ -51,7 +51,7 @@ cutils.default_metadata_om = ObjectManager { } function cutils.evaluateRulesApplyProperties (properties, name) - local matched, mprops = Settings.apply_rule (name, properties) + local matched, mprops = Conf.apply_rules (name, properties) if (matched and mprops) then for k, v in pairs (mprops) do diff --git a/src/scripts/monitors/alsa-midi.lua b/src/scripts/monitors/alsa-midi.lua index fa8fe463..8e06aec8 100644 --- a/src/scripts/monitors/alsa-midi.lua +++ b/src/scripts/monitors/alsa-midi.lua @@ -6,14 +6,11 @@ -- SPDX-License-Identifier: MIT local defaults = {} -defaults.node_properties = Json.Object { - ["node.name"] = "Midi-Bridge", - ["api.alsa.disable-longname"] = true -} +defaults.node_properties = Json.Object {} local config = {} -config.node_properties = Settings.parse_object_safe ( - "monitor.alsa.midi.node-properties", defaults.node_properties) +config.node_properties = Conf.get_section ( + "monitor.alsa.midi.node-properties", defaults.node_properties):parse () SND_PATH = "/dev/snd" SEQ_NAME = "seq" diff --git a/src/scripts/monitors/alsa.lua b/src/scripts/monitors/alsa.lua index f105129a..3ddf6d91 100644 --- a/src/scripts/monitors/alsa.lua +++ b/src/scripts/monitors/alsa.lua @@ -12,22 +12,19 @@ defaults.reserve_priority = -20 defaults.reserve_application_name = "WirePlumber" defaults.jack_device = false defaults.properties = Json.Object {} -defaults.vm_node_defaults = Json.Object { - ["api.alsa.period-size"] = 256, - ["api.alsa.headroom"] = 8192 -} +defaults.vm_node_defaults = Json.Object {} local config = {} -config.reserve_priority = Settings.parse_int_safe ( +config.reserve_priority = Conf.get_value_int ("wireplumber.settings", "monitor.alsa.reserve-priority", defaults.reserve_priority) -config.reserve_application_name = Settings.parse_string_safe ( +config.reserve_application_name = Conf.get_value_string ("wireplumber.settings", "monitor.alsa.reserve-application-name", defaults.reserve_application_name) -config.jack_device = Settings.parse_boolean_safe ( +config.jack_device = Conf.get_value_boolean ("wireplumber.settings", "monitor.alsa.jack-device", defaults.jack_device) -config.properties = Settings.parse_object_safe ( - "monitor.alsa.properties", defaults.properties) -config.vm_node_defaults = Settings.parse_object_safe ( - "monitor.alsa.vm.node.defaults", defaults.vm_node_defaults) +config.properties = Conf.get_section ( + "monitor.alsa.properties", defaults.properties):parse () +config.vm_node_defaults = Conf.get_section ( + "monitor.alsa.vm.node.defaults", defaults.vm_node_defaults):parse () -- unique device/node name tables device_names_table = nil @@ -270,7 +267,8 @@ function prepareDevice(parent, id, obj_type, factory, properties) end -- apply properties from rules defined in JSON .conf file - local applied = cutils.evaluateRulesApplyProperties (properties, "monitor.alsa.rules") + local applied = cutils.evaluateRulesApplyProperties (properties, + "monitor.alsa.rules") if not applied then applyDefaultDeviceProperties (properties) end diff --git a/src/scripts/monitors/bluez-midi.lua b/src/scripts/monitors/bluez-midi.lua index 5ca2888c..46858975 100644 --- a/src/scripts/monitors/bluez-midi.lua +++ b/src/scripts/monitors/bluez-midi.lua @@ -12,10 +12,10 @@ defaults.properties = Json.Object {} defaults.servers = Json.Array { "bluez_midi.server" } local config = {} -config.properties = Settings.parse_object_safe ( - "monitor.bluetooth-midi.properties", defaults.properties) -config.servers = Settings.parse_array_safe ( - "monitor.bluetooth-midi.servers", defaults.servers) +config.properties = Conf.get_section ( + "monitor.bluetooth-midi.properties", defaults.properties): parse () +config.servers = Conf.get_section ( + "monitor.bluetooth-midi.servers", defaults.servers): parse () -- unique device/node name tables node_names_table = nil @@ -60,7 +60,7 @@ function createNode(parent, id, type, factory, properties) properties["api.glib.mainloop"] = "true" -- apply properties from bluetooth.conf - cutils.evaluateRulesApplyProperties (properties, "monitor.bluetooth-midi") + cutils.evaluateRulesApplyProperties (properties, "monitor.bluetooth-midi.rules") local latency_offset = properties["node.latency-offset-msec"] properties["node.latency-offset-msec"] = nil @@ -116,7 +116,7 @@ function createServers() ["factory.name"] = "api.bluez5.midi.node", ["api.glib.mainloop"] = "true", } - cutils.evaluateRulesApplyProperties (node_props, "monitor.bluetooth-midi") + cutils.evaluateRulesApplyProperties (node_props, "monitor.bluetooth-midi.rules") local latency_offset = node_props["node.latency-offset-msec"] node_props["node.latency-offset-msec"] = nil diff --git a/src/scripts/monitors/bluez.lua b/src/scripts/monitors/bluez.lua index bee38bc2..66c5c40a 100644 --- a/src/scripts/monitors/bluez.lua +++ b/src/scripts/monitors/bluez.lua @@ -10,13 +10,11 @@ local COMBINE_OFFSET = 64 local cutils = require ("common-utils") local defaults = {} -defaults.properties = Json.Object { - ["api.bluez5.connection-info"] = true -} +defaults.properties = Json.Object {} local config = {} -config.properties = Settings.parse_object_safe ( - "monitor.bluetooth.properties", defaults.properties) +config.properties = Conf.get_section ( + "monitor.bluetooth.properties", defaults.properties): parse () devices_om = ObjectManager { Interest { @@ -282,7 +280,7 @@ function createNode(parent, id, type, factory, properties) end -- apply properties from bluetooth.conf - cutils.evaluateRulesApplyProperties (properties, "monitor.bluetooth") + cutils.evaluateRulesApplyProperties (properties, "monitor.bluetooth.rules") -- create the node; bluez requires "local" nodes, i.e. ones that run in -- the same process as the spa device, for several reasons @@ -344,7 +342,8 @@ function createDevice(parent, id, type, factory, properties) properties["api.bluez5.id"] = id -- apply properties from bluetooth.conf - local applied = cutils.evaluateRulesApplyProperties (properties, "monitor.bluetooth") + local applied = cutils.evaluateRulesApplyProperties (properties, + "monitor.bluetooth.rules") if not applied then applyDefaultDeviceProperties (properties) end diff --git a/src/scripts/monitors/libcamera.lua b/src/scripts/monitors/libcamera.lua index b03b7841..bcc885fe 100644 --- a/src/scripts/monitors/libcamera.lua +++ b/src/scripts/monitors/libcamera.lua @@ -11,8 +11,8 @@ local defaults = {} defaults.properties = Json.Object {} local config = {} -config.properties = Settings.parse_object_safe ( - "monitor.libcamera.properties", defaults.properties) +config.properties = Conf.get_section ( + "monitor.libcamera.properties", defaults.properties): parse () function findDuplicate(parent, id, property, value) for i = 0, id - 1, 1 do diff --git a/src/scripts/monitors/v4l2.lua b/src/scripts/monitors/v4l2.lua index 78c2766e..a416b980 100644 --- a/src/scripts/monitors/v4l2.lua +++ b/src/scripts/monitors/v4l2.lua @@ -11,8 +11,8 @@ local defaults = {} defaults.properties = Json.Object {} local config = {} -config.properties = Settings.parse_object_safe ( - "monitor.v4l2.properties", defaults.properties) +config.properties = Conf.get_section ( + "monitor.v4l2.properties", defaults.properties): parse () function findDuplicate(parent, id, property, value) for i = 0, id - 1, 1 do diff --git a/src/scripts/policy-bluetooth.lua b/src/scripts/policy-bluetooth.lua index 2d12ca24..05727749 100644 --- a/src/scripts/policy-bluetooth.lua +++ b/src/scripts/policy-bluetooth.lua @@ -31,20 +31,15 @@ local cutils = require ("common-utils") local defaults = {} defaults.use_persistent_storage = true defaults.use_headset_profile = true -defaults.app_settings = Json.Array { - "Firefox", "Chromium input", "Google Chrome input", "Brave input", - "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine", - "Telegram Desktop", "telegram-desktop", "linphone", "Mumble", - "WEBRTC VoiceEngine", "Skype" -} +defaults.app_settings = Json.Array {} local config = {} -config.use_persistent_storage = Settings.parse_boolean_safe ( +config.use_persistent_storage = Conf.get_value_boolean ("wireplumber.settings", "policy.bluetooth.use-persistent-storage", defaults.use_persistent_storage) -config.use_headset_profile = Settings.parse_boolean_safe ( +config.use_headset_profile = Conf.get_value_boolean ("wireplumber.settings", "policy.bluetooth.media-role.use-headset-profile", defaults.use_headset_profile) -config.apps_setting = Settings.parse_array_safe ( - "policy.bluetooth.media-role.applications", defaults.app_settings) +config.apps_setting = Conf.get_value ("wireplumber.settings", + "policy.bluetooth.media-role.applications", defaults.app_settings): parse () state = nil headset_profiles = nil @@ -60,17 +55,17 @@ function handlePersistantSetting (enable) end end -local function settingsChangedCallback (_, setting, _) - if setting == "policy.bluetooth.use-persistent-storage" then - config.use_persistent_storage = Settings.parse_boolean_safe - ("policy.bluetooth.use-persistent-storage", config.use_persistent_storage) +local function settingsChangedCallback (_, setting, json) + if setting == "policy.bluetooth.use-persistent-storage" and + json:is_boolean () then + config.use_persistent_storage = json:parse () handlePersistantSetting (config.use_persistent_storage) - elseif setting == "policy.bluetooth.media-role.use-headset-profile" then - config.use_headset_profile = Settings.parse_boolean_safe - ("policy.bluetooth.media-role.use-headset-profile", config.use_headset_profile) - elseif setting == "policy.bluetooth.media-role.applications" then - local new_apps_setting = Settings.parse_array_safe - ("policy.bluetooth.media-role.applications", Json.Array {}) + elseif setting == "policy.bluetooth.media-role.use-headset-profile" and + json:is_boolean () then + config.use_headset_profile = json:parse () + elseif setting == "policy.bluetooth.media-role.applications" + and json:is_array () then + local new_apps_setting = json:parse () if #new_apps_setting > 0 then config.apps_setting = new_apps_setting loadAppNames (config.apps_setting) diff --git a/src/scripts/policy-endpoint-client-links.lua b/src/scripts/policy-endpoint-client-links.lua index 50363a7c..2fc78c44 100644 --- a/src/scripts/policy-endpoint-client-links.lua +++ b/src/scripts/policy-endpoint-client-links.lua @@ -10,10 +10,10 @@ defaults.duck_level = 0.3 defaults.roles = Json.Object {} local config = {} -config.duck_level = Settings.parse_float_safe ( +config.duck_level = Conf.get_value_float ("wireplumber.settings", "policy.default.duck-level", defaults.duck_level) -config.roles = Settings.parse_object_safe ( - "endpoints-roles", defaults.roles) +config.roles = Conf.get_section ( + "endpoint-roles", defaults.roles):parse () function findRole(role) if role and not config.roles[role] then diff --git a/src/scripts/policy-endpoint-client.lua b/src/scripts/policy-endpoint-client.lua index cb7af7c1..9184b17b 100644 --- a/src/scripts/policy-endpoint-client.lua +++ b/src/scripts/policy-endpoint-client.lua @@ -11,8 +11,8 @@ local defaults = {} defaults.roles = Json.Object {} local config = {} -config.roles = Settings.parse_object_safe ( - "endpoints-roles", defaults.roles) +config.roles = Conf.get_section ( + "endpoint-roles", defaults.roles):parse () local self = {} self.scanning = false diff --git a/src/scripts/policy-endpoint-device.lua b/src/scripts/policy-endpoint-device.lua index 2dbd06e8..8d71810b 100644 --- a/src/scripts/policy-endpoint-device.lua +++ b/src/scripts/policy-endpoint-device.lua @@ -9,7 +9,7 @@ local defaults = {} defaults.follow = true local config = {} -config.follow = Settings.parse_boolean_safe ( +config.follow = Conf.get_value_boolean ("wireplumber.settings", "policy.default.follow", defaults.follow) local self = {} diff --git a/src/scripts/static-endpoints.lua b/src/scripts/static-endpoints.lua index 608d42c8..e5541eee 100644 --- a/src/scripts/static-endpoints.lua +++ b/src/scripts/static-endpoints.lua @@ -11,8 +11,8 @@ local defaults = {} defaults.endpoints = Json.Object {} local config = {} -config.endpoints = Settings.parse_object_safe ( - "endpoints", defaults.endpoints) +config.endpoints = Conf.get_section ( + "endpoints", defaults.endpoints):parse () function createEndpoint (factory_name, properties) -- create endpoint diff --git a/tests/wp/settings.c b/tests/wp/settings.c index 42a1cc35..f64fc3fa 100644 --- a/tests/wp/settings.c +++ b/tests/wp/settings.c @@ -268,12 +268,6 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data) g_assert_nonnull (j2); g_assert_true (wp_spa_json_parse_boolean (j2, &value)); g_assert_true (value); - - value = wp_settings_parse_boolean_safe (s, "test-setting2", FALSE); - g_assert_true (value); - - value = wp_settings_parse_boolean_safe (s, "test-setting-undefined", TRUE); - g_assert_true (value); } { @@ -284,12 +278,6 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data) g_assert_nonnull (j); g_assert_true (wp_spa_json_parse_int (j, &value)); g_assert_cmpint (value, ==, -20); - - value = wp_settings_parse_int_safe (s, "test-setting3-int", 3); - g_assert_cmpint (value, ==, -20); - - value = wp_settings_parse_int_safe (s, "test-setting-undefined", 3); - g_assert_cmpint (value, ==, 3); } { @@ -303,20 +291,6 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data) g_assert_cmpstr (value, ==, "blahblah"); } - { - g_autofree gchar *value = NULL; - value = wp_settings_parse_string_safe (s, "test-setting4-string", - "fallback-string"); - g_assert_cmpstr (value, ==, "blahblah"); - } - - { - g_autofree gchar *value = NULL; - value = wp_settings_parse_string_safe (s, "test-setting-undefined", - "fallback-string"); - g_assert_cmpstr (value, ==, "fallback-string"); - } - { g_autofree gchar *value = NULL; g_autoptr (WpSpaJson) j = NULL; @@ -340,12 +314,6 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data) g_assert_nonnull (j2); g_assert_true (wp_spa_json_parse_float (j2, &value)); g_assert_cmpfloat_with_epsilon (value, 0.4, 0.001); - - value = wp_settings_parse_float_safe (s, "test-setting-float1", 4.14); - g_assert_cmpfloat_with_epsilon (value, 3.14, 0.001); - - value = wp_settings_parse_float_safe (s, "test-setting-undefined", 4.14); - g_assert_cmpfloat_with_epsilon (value, 4.14, 0.001); } /* test the wp_settings_get_instance () API */ @@ -447,170 +415,6 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data) } } -static void -test_rules (TestSettingsFixture *self, gconstpointer data) -{ - WpSettings *s = self->s; - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string2", "juggler", - NULL); - - g_assert_true (wp_settings_apply_rule (s, "rule_one", props, NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string2", "jugglr", - NULL); - - g_assert_false (wp_settings_apply_rule (s, "rule_one", props, NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string1", "copper", - "test-int1", "100", - NULL); - - g_assert_true (wp_settings_apply_rule (s, "rule_one", props, NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string1", "copper", - NULL); - - g_assert_false (wp_settings_apply_rule (s, "rule_one", props, NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string2", "juggler", - NULL); - gint before = wp_properties_get_count (props), after = 0; - guint prop_int1 = 0; - g_assert_true (wp_settings_apply_rule (s, "rule_one", props, NULL)); - after = wp_properties_get_count (props); - - g_assert_cmpint (after-before, ==, 2); - g_assert_cmpstr (wp_properties_get(props, "prop-string1"), ==, "metal"); - g_assert_cmpstr (wp_properties_get(props, "prop-string2"), ==, NULL); - g_assert_cmpstr (wp_properties_get(props, "prop-int1"), ==, "123"); - spa_atou32 (wp_properties_get(props, "prop-int1"), &prop_int1, 0); - g_assert_cmpint (prop_int1, ==, 123); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string4", "ferrous", - "test-int2", "100", - "test-string5", "blend", - NULL); - gint before = wp_properties_get_count (props), after = 0; - guint prop_int2 = 0; - g_assert_true (wp_settings_apply_rule (s, "rule_one", props, NULL)); - after = wp_properties_get_count (props); - - g_assert_cmpint (after-before, ==, 3); - g_assert_cmpstr (wp_properties_get(props, "prop-string1"), ==, NULL); - g_assert_cmpstr (wp_properties_get(props, "prop-string2"), ==, "standard"); - g_assert_cmpstr (wp_properties_get(props, "prop-int2"), ==, "26"); - spa_atou32 (wp_properties_get(props, "prop-int2"), &prop_int2, 0); - g_assert_cmpint (prop_int2, ==, 26); - g_assert_true (spa_atob(wp_properties_get(props, "prop-bool1"))); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test-string6", "ethylene", - "test-int2", "625", - "test-string5", "blend", - NULL); - g_autoptr (WpProperties) applied_props = wp_properties_new_empty (); - guint prop_int2 = 0; - g_assert_false (wp_settings_apply_rule (s, "rule_one", props, NULL)); - g_assert_true (wp_settings_apply_rule (s, "rule_two", props, - applied_props)); - - g_assert_cmpint (wp_properties_get_count (applied_props), ==, 2); - g_assert_cmpstr (wp_properties_get(applied_props, "prop-string1"), - ==, NULL); - g_assert_cmpstr (wp_properties_get(applied_props, "prop-string2"), - ==, "spray"); - g_assert_cmpstr (wp_properties_get(applied_props, "prop-int2"), ==, "111"); - spa_atou32 (wp_properties_get(applied_props, "prop-int2"), &prop_int2, 0); - g_assert_cmpint (prop_int2, ==, 111); - g_assert_false (spa_atob(wp_properties_get(applied_props, "prop-bool1"))); - } - - /* test the regular experession syntax */ - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test.string6", "metal.iron", - "test.table.entry", "true", - NULL); - g_autoptr (WpProperties) applied_props = wp_properties_new_empty (); - g_assert_false (wp_settings_apply_rule (s, "rule_one", props, NULL)); - g_assert_false (wp_settings_apply_rule (s, "rule_two", props, - applied_props)); - g_assert_true (wp_settings_apply_rule (s, "rule_three", props, - applied_props)); - - g_assert_cmpint (wp_properties_get_count (applied_props), ==, 3); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.string1"), - ==, NULL); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.state"), - ==, "solid"); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.example"), - ==, "ferrous"); - g_assert_true (spa_atob(wp_properties_get(applied_props, - "prop.electrical.conductivity"))); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test.string6", "metal.iron", - "test.table.entry", "false", - NULL); - g_assert_false (wp_settings_apply_rule (s, "rule_three", props, - NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test.string6", "metl.iron", - "test.table.entry", "true", - NULL); - g_assert_false (wp_settings_apply_rule (s, "rule_three", props, - NULL)); - } - - { - g_autoptr (WpProperties) props = wp_properties_new ( - "test.string6", "gas.neon", - "test.table.entry", "maybe", - NULL); - g_autoptr (WpProperties) applied_props = wp_properties_new_empty (); - g_assert_false (wp_settings_apply_rule (s, "rule_one", props, NULL)); - g_assert_false (wp_settings_apply_rule (s, "rule_two", props, - applied_props)); - g_assert_true (wp_settings_apply_rule (s, "rule_three", props, - applied_props)); - - g_assert_cmpint (wp_properties_get_count (applied_props), ==, 3); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.string1"), - ==, NULL); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.state"), - ==, "gas"); - g_assert_cmpstr (wp_properties_get(applied_props, "prop.example"), - ==, "neon"); - g_assert_false (spa_atob(wp_properties_get(applied_props, - "prop.electrical.conductivity"))); - } -} - void wp_settings_changed_callback (WpSettings *obj, const gchar *setting, WpSpaJson *json, gpointer user_data) { @@ -640,7 +444,6 @@ void wp_settings_changed_callback (WpSettings *obj, const gchar *setting, } } - static void test_callbacks (TestSettingsFixture *self, gconstpointer data) { @@ -722,8 +525,6 @@ main (gint argc, gchar *argv[]) test_metadata_setup, test_metadata, test_metadata_teardown); g_test_add ("/wp/settings/wpsettings-creation-get", TestSettingsFixture, NULL, test_wpsettings_setup, test_wpsettings, test_wpsettings_teardown); - g_test_add ("/wp/settings/wpsettings-creation-rules", TestSettingsFixture, NULL, - test_wpsettings_setup, test_rules, test_wpsettings_teardown); g_test_add ("/wp/settings/wpsettings-callbacks", TestSettingsFixture, NULL, test_wpsettings_setup, test_callbacks, test_wpsettings_teardown); diff --git a/tests/wplua/scripts/settings.lua b/tests/wplua/scripts/settings.lua index 85c49438..80250b46 100644 --- a/tests/wplua/scripts/settings.lua +++ b/tests/wplua/scripts/settings.lua @@ -17,24 +17,12 @@ value = Settings.get ("test-setting2"):parse() assert ("boolean" == type (value)) assert (value == true) -value = Settings.parse_boolean_safe ("test-setting2", false) -assert (value == true) - -value = Settings.parse_boolean_safe ("test-setting-undefined", true) -assert (value == true) - -- test settings _get_int () value = Settings.get ("test-setting3-int"):parse() assert ("number" == type (value)) assert (value == -20) -value = Settings.parse_int_safe ("test-setting3-int", 10) -assert (value == -20) - -value = Settings.parse_int_safe ("test-setting-undefined", 10) -assert (value == 10) - -- test settings _get_string () value = Settings.get ("test-setting4-string"):parse() @@ -45,12 +33,6 @@ value = Settings.get ("test-setting5-string-with-quotes"):parse() assert ("string" == type (value)) assert (value == "a string with \"quotes\"") -value = Settings.parse_string_safe ("test-setting4-string", "fallback-string") -assert (value == "blahblah") - -value = Settings.parse_string_safe ("test-setting-undefined", "fallback-string") -assert (value == "fallback-string") - -- test settings _get_float () value = Settings.get ("test-setting-float1"):parse() @@ -60,34 +42,13 @@ assert ((value - 3.14) < 0.00001) value = Settings.get ("test-setting-float2"):parse() assert ((value - 0.4) < 0.00001) -value = Settings.parse_float_safe ("test-setting-float1", 4.14) -assert ((value - 3.14) < 0.00001) - -value = Settings.parse_float_safe ("test-setting-undefined", 4.14) -assert ((value - 4.14) < 0.00001) - -- test settings _get () value = Settings.get ("test-setting-json") assert (value ~= nil) assert (value:is_array()) assert (value:get_data() == "[1, 2, 3]") -value = Settings.parse_array_safe ("test-setting-json", Json.Array {}) -assert (value ~= nil) -assert (value[1] == 1) -assert (value[2] == 2) -assert (value[3] == 3) - -value = Settings.parse_array_safe ("test-setting-undefined", nil) -assert (value ~= nil) -assert (#value == 0) - -value = Settings.parse_array_safe ("test-setting-undefined", Json.Array { 1, 2 }) -assert (value ~= nil) -assert (value[1] == 1) -assert (value[2] == 2) - -value = Settings.get ("test-setting-json2") +value = Settings.get ("test-setting-json2", "test-settings") assert (value ~= nil) assert (value:is_array()) assert (value:get_data() == @@ -111,132 +72,6 @@ assert (val.key1 == "value") assert (val.key2 == 2) assert (val.key3 == true) -value = Settings.parse_object_safe ("test-setting-json3", Json.Object {}) -assert (value ~= nil) -assert (value.key1 == "value") -assert (value.key2 == 2) -assert (value.key3 == true) - -value = Settings.parse_object_safe ("test-setting-undefined", nil) -assert (value ~= nil) -assert (#value == 0) - -value = Settings.parse_object_safe ("test-setting-undefined", Json.Object { key1 = "value", key2 = 2}) -assert (value ~= nil) -assert (value.key1 == "value") -assert (value.key2 == 2) - --- test rules --- test #1 -local cp = { - ["test-string2"]="juggler" -} -local ap = {} - -local applied, ap = Settings.apply_rule( "rule_one", cp) - -assert (applied == true) -assert (ap["prop-string1"] == "metal") -assert (ap["prop-int1"] == "123") -assert (ap["blah blah"] == nil) - --- test #2 -local cp = { - ["test-string2"]="jugler" -} -local ap = {} - -local applied, ap = Settings.apply_rule ("rule_one", cp) - -assert (applied == false) - --- test #3 -local cp = { - ["test-string4"] = "ferrous", - ["test-int2"] = "100", - ["test-string5"] = "blend" -} - -local applied, ap = Settings.apply_rule ("rule_one", cp) - -assert (applied == true) -assert (ap["prop-string1"] == nil) -assert (ap["prop-string2"] == "standard") -assert (ap["prop-int2"] == "26") -assert (ap["prop-bool1"] == "true") - --- test #4 -local cp = { - ["test-string6"] = "alum", -} - -local applied, ap = Settings.apply_rule ("rule_one", cp) - -assert (applied == false) - --- test #5 -local cp = { - ["test-string6"] = "alum", - ["test-int3"] = "24", -} - -local applied, ap = Settings.apply_rule ("rule_one", cp) - -assert (applied == true) -assert (ap["prop-string1"] == nil) -assert (ap["prop-string2"] == "standard") -assert (ap["prop-int2"] == "26") -assert (ap["prop-bool1"] == "true") - --- test #6 --- test regular expression syntax -local cp = { - ["test.string6"] = "metal.ferrous", - ["test.table.entry"] = "yes", -} - -local applied, ap = Settings.apply_rule ("rule_three", cp) - -assert (applied == false) - --- test #7 -local cp = { - ["test.string6"] = "metal.ferrous", - ["test.table.entry"] = "true", -} - -local applied, ap = Settings.apply_rule ("rule_three", cp) - -assert (applied == true) -assert (ap["prop.electrical.conductivity"] == "true") -assert (ap["prop.state"] == "solid") -assert (ap["prop.example"] == "ferrous") - --- test #8 -local cp = { - ["test.string6"] = "gas.xenon", - ["test.table.entry"] = "maybe", -} - -local applied, ap = Settings.apply_rule ("rule_three", cp) - -assert (applied == true) -assert (ap["prop.electrical.conductivity"] == "false") -assert (ap["prop.state"] == "gas") -assert (ap["prop.example"] == "neon") - --- test #9 -local cp = { - ["test-string6-wildcard"] = "wild_cat", -} - -local applied, ap = Settings.apply_rule ("rule_three", cp) - -assert (applied == true) -assert (ap["prop.electrical.conductivity"] == "true") -assert (ap["prop.state"] == "solid") -assert (ap["prop.example"] == "ferrous") - -- test callbacks metadata_om = ObjectManager {