The wp_settings_delete_all() API internally uses wp_metadata_clear() to clear
all the keys in the persistent-sm-settings metadata object. This call emits
the metadata changed signal with both 'key' and 'value' set to NULL. When that
happens, we need to clear all settings from the state file.
We do not use these APIs, so there's no point in keeping them.
Realistically, every component that needs a section just does its
own parsing on it, so the _get_value() functions are not needed.
The fallback in _get_section() is also not needed, as we always
pass NULL and then test for it. In Lua, however, it seems we are
using the fallback to return an empty object, so that getting
a section does not expand to multiple lines of code. For that reason,
I have kept the syntax there and implemented it in the bindings layer.
Changes:
- Configuration files are no longer located by libpipewire,
which allows us to control the paths that are being looked up.
This is a requirement for installations where pipewire and
wireplumber are built using different prefixes, in which case
the configuration files of wireplumber end up being installed in
a place that libpipewire doesn't look into...
- The location of conf files is now again $prefix/share/wireplumber,
/etc/wireplumber and $XDG_CONFIG_HOME/wireplumber, instead of using
the pipewire directories. Also, since the previous commits, we now
also support $XDG_CONFIG_DIRS/wireplumber (typically /etc/xdg/wireplumber)
and $XDG_DATA_DIRS/wireplumber for system-wide configuration.
- Since libpipewire doesn't expose the parser, we now also do the
parsing of sections ourselves. This has the advantage that we can
optimize it a bit for our use case.
- The WpConf API has changed to not be a singleton and it is a
property of WpCore instead. The configuration is now expected
to be opened before the core is created, which allows the caller
to identify configuration errors in advance. By not being a singleton,
we can also reuse the WpConf API to open other SPA-JSON files.
- WpConf also now has a lazy loading mechanism. The configuration
files are mmap'ed and the various sections are located in advance,
but not parsed until they are actually requested. Also, the sections
are not copied in memory, unlike what happens in libpipewire. They
are only copied when merging is needed.
- WpCore now disables loading of a configuration file in pw_context,
if a WpConf is provided. This is to have complete control here.
The 'context.spa-libs' and 'context.modules' sections are still
loaded, but we load them in WpConf and pass them down to pw_context
for parsing. If a WpConf is not provided, pw_context is left to load
the default configuration file (client.conf normally).
This patch improves module-settings to load the settings schema into a
'schema-sm-settings' metadata for clients to know what values types and range
are accepted for each particular setting. This settings schema is defined in
the wireplumber.conf, under a new section called 'wireplumber.settings.schema'.
Similar to 'default.audio.sink', a setting from sm-settings should never be
removed when the associated persistent setting is removed. Only settings from
persistent-sm-settings can be removed, like 'default.configured.audio.sink'.
This patch removes the 'settings.persistent' option from the configuration as it
only allowed making settings persistent globally instead of individually. This
issue has been addressed in a simpler way by creating a 'persistent-sm-settings'
metadata. If a user wants to make a setting persistent, he can change the
'persistent-sm-settings' metadata object, if the user does not want to make a
persistent change, he can use the 'sm-settings' metadata object. Any changes in
the 'persistent-sm-settings' metadata will be also reflected in the 'sm-settings'
metadata object.
When running multi-instance setups or when clients like wpctl want to
access the WpSettings instance, it makes no sense to load the entire
module-settings, which will also create sm-settings metadata instances.
The previous naming convention was confusing because it did not make
it explicit that the string is not being copied. We had this wrong already
in the Lua bindings and thanks to some miracle it hasn't backfired so far
(it was using the "wrap" behaviour with a string that doesn't stay alive).
In some places we actually need the "copy" behaviour and in some other
places we need the "wrap" behaviour, so let's have both variants available.
The intention is to make checks for enabled log topics faster.
Every topic has its own structure that is statically defined in the file
where the logs are printed from. The structure is initialized transparently
when it is first used and it contains all the log level flags for the levels
that this topic should print messages. It is then checked on the wp_log()
macro before printing the message.
Topics from SPA/PipeWire are also handled natively, so messages are printed
directly without checking if the topic is enabled, since the PipeWire and SPA
macros do the checking themselves.
Messages coming from GLib are checked inside the handler.
An internal WpLogFields object is used to manage the state of each log
message, populating all the fields appropriately from the place they
are coming from (wp_log, spa_log, glib log), formatting the message and
then printing it. For printing to the journald, we still use the glib
message handler, converting all the needed fields to GLogField on demand.
That message handler does not do any checks for the topic or the level, so
we can just call it to send the message.
This change completely refactors the way components are loaded in wireplumber:
- The module_init() function must return a GObject now. This object is either
a WpPlugin or a WpSiFactory in the current modules.
- When the component loader initializes a module, it automatically registers
the WpPlugin or WpSiFactory with their respective methods. There is no need
to register the WpPlugin or WpSiFactory in the module now.
- The wp_core_load_component() API has been refactored to be asynchronows. This
allows the component loader to automatically activate WpPlugin objects, and
therefore allows the application to directly get the WpPlugin without having
to find it. This simplifies a lot of things.
- The 'ifexists' and 'nofail' component flags now work even if the respective
WpPlugin could not be activated.
- The code that loads components in main.c has also been simplified a lot,
and the option to load dangling components has also been removed.
After the creation of metadata with config data, m-settings will also need to
trigger the init of WpSettings Object/API. Earlier this was done in main.c as
part of init transition but the logic there is much more generalized now and so
it has been moved here.
We need to use WpSpaJson to parse the values in WpSettings. This is because the
wireplumber configuration is written in JSON, so WpSettings should only hold
JSON values. To fix this, 2 API changes have been done:
- wp_settings_get_int() only accepts gint values, instead of gint64 values. This
is because the WpSpaJson API only parses int values, like spa_json_parse_int().
- wp_settings_get_string() now returns a newly allocated string, this is because
the string needs to be decoded in case it has quotes.
Add a null check when iterator gets the value to detect the end of the
JSON object, this will ensure the rest of the code that operates on the
value is bypassed.
Still it must be noted that an empty setting screws up the following
settings and behavior is undefined, this is the limiation in the
spa-json parsing.
- Move the endpoints defination to wireplumber.conf under a new section
in the form of two JSON objects, namely endpoints and
endpoints-roles.
- Treat the endpoint objects as settings, for the sake of loading,
parsing and querying.
- m-settings loads the objects and WpSettings parses them as any other
settings.
- Make the following changes in endpoint scripts.
- Get the endpoint settings using the _get_string() API.
- Parse and use the data.
- Remove references to the config/lua
- Remove the endpoints defination in config/lua
- 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.
- settings.c tests conf file loading & parsing, metadata updates,
wpsetttings object creation and its API.
- settings.lua tests the API from lua scripts.
- Add a sample settings.conf file, this file contains sections copied
over from client.conf along with the settings section. Add a file
each for wp side and lua side of scripts.
- Make changes in base test infrastructure to take a custom conf file.
- Enhance the wp_settings_get_instance_api() to be take metadata_name
parameter. So, Wpsetttings is now a singleton instance for a given
metadata file.
- Enhance the m-settings module also to be take metadata_name parameter.
this is handy for lua side of tests as its cumbersome to do this is
lua.
- WpSettings is a singleton object which attaches itself to the core
and registry, it provides a get_instance () for its clients.
- WpSettings provides API to get/set wireplumber settings and rules.
- main.c loads the new object and makes sure it is available for
for all the modules and scripts. This is achieved by introducing
a new activation step.
- Add the lua bindings for get_setting API.
- parse settings from .conf file.
- create "sm-settings" metadata and copy settings as key value pairs
to it.
- put in place "persistent" behavior, control it with a special
setting.
- when persistent behavior is enabled.
- create a state file and update settings to it.
- monitor changes in the metadata and update the settings to state
file.