We only want to restore the saved profile when it is available, when
it is not available and there was no change in best profile, leave
the profile as it is.
Keep track of the best profile. Only try to switch away from the
saved profile when something changed and the saved profile is not
available.
This makes it possible to select an unavailable profile but when
something is changed, it will switch away from it.
A node.target property of -1 also means to follow the default
sink/source. The ALSA plugin might use this to select the
target node and would otherwise not move to the new default sink.
Every time a new operation is started, schedule a rescan. This
ensures that there are no more pending actions before the policy
module scans the nodes.
This has the effect that all devices and nodes are up to data and
ready to be used by policy-node.
Fixes#789
Move the profile switching from default-route to the default-profile
module. This makes more sense and it also allows us to restore the
saved profile when it becomes available.
Make default-profile always check if the saved profile can be restored
before attempting to switch to the best profile.
Default-route now just monitors profile changes and restores the
routes associated with it.
See #466
Don't just store the id in the metadata but a JSON object with
the node name. This makes it possible to easily introspect the
metadata and also extend the metadata with more fields later.
Instead of matching the metadata id to the global ids we now
have to match it against the name.
The session manager might be configured without metadata support
so check this before attempting to use the metadata. It's not
really a problem because the default sink/source can only be
changed with the pulseaudio API, which activates metadata.
The prefix was used to filter the properties when loading and
saving but since the conversion to the core provided functions, this
feature is not longer available.
It's not exactly a problem, we could implement the filtering ourselves
afterwards but there is little point because we just ignore the unknown
items and never write invalid items.
1) detect port changes
2) restore or save port changes
3) if port changes:
check and restore the best profile
else check and restore the best ports
4) if profile changed, check and restore best ports
See #533
See #708
First check all the routes to see if anything changed. If there is
a change check if we need a profile switch.
Then check all the active routes and restore state when they changed.
Add save property to Profile and Route params to notify the session
manager that they should be saved. Let the session manager only save
the Profile and Routes with the save flag.
Make pulse-server set the save flag on Profile and Route changes.
The result is that we can make a difference between user requested
changes and automatical changes and only remember the user preferences.
When a port changes availability, first check if we need to perform
a profile switch, if not select the new best port.
When duplicate objects are created, the new object has missed its
registry_global event, and is missing its proxy.
In this case, bind a proxy for the new object.
sm_object may be owned by either (i) monitors, created via
sm_media_session_create/export*, or (ii) registry, via
registry_global+bind_object. However, registry adds the objects to its
globals list when their proxy appears, even if it does not own them.
Only owner should call sm_object_destroy which unrefs obj->handle,
because the sm_object structure is stored inside the handle's user_data
and becomes invalid afterward.
The sm_object_destroy call removes the object from the registry globals
map, so if monitor calls first, there is no problem. However, sometimes
the registry wins the race.
Previously, registry did sm_object_destroy regardless of whether it owns
the object or not, possibly causing the monitor's sm_object_destroy to
refer to freed memory. This could cause segfaults, e.g.
CARD=XX:XX:XX:XX:XX:XX
bluetootctl connect $CARD
while true; do pactl set-card-profile bluez_card.$CARD a2dp-sink; pactl set-card-profile bluez_card.$CARD off; done
leads to a race between bluez5_remove_node and registry_global_remove,
and problems appear when the latter wins. (As usual, if it doesn't
segfault, a heisenbug appears instead.)
Fix this by keeping track who owns the objects, and having registry
destroy the objects only if it owns them. Otherwise, it just removes
them from its lists.
Also call pw_proxy_unref unconditionally in sm_object_destroy, so its
asserts catch refcounting errors (although now there shouldn't be any).
***
Another problem is conflict between bound_proxy and register_global,
which generates duplicate objects with the same id. We resolve this by
keeping the object not owned by the registry and discarding the other
one.
This fixes a memory leak, and possible consistency problems in session
modules (due to session_create events for different objects with same
id; now there will be paired session_remove ones in between).
Replace unwanted chars in the name with _. This makes it compatible
with pulseaudio names and avoids problems with regex.
Replace unwanred chars in the nick with ' '. This ensures JACK
clients don't receive ':' in the device names, which cause it to
fail when parsing the ports.
See #714 and #130
Make methods to load_config and load/save state. For now the config
and state directories are the same but it might not be. Implement
the search path for all config/state files as:
$XDG_CONFIG_HOME/[$prefix]/$name
$HOME/.config/[$prefix]/$name
$PIPEWIRE_CONFIG_DIR/pipewire/[$prefix]/$name
/etc/pipewire/[$prefix]/$name
Make some config files for jack and RT clients. Make pw-cat use the
client-rt config.
Use core state and config management in media-session.
Move all session manager state and config files to the build dir and
set the PIPEWIRE_CONFIG_DIR to this build dir.
Move the daemon config file loading to a new conf.c file used by
the context to load the configuration. This replaces the module
profiles and some hacks to move properties around.
If there is nothing other specified with $PIPEWIRE_CONFIG_NAME or
a property, the client.conf file is loaded as a fallback.
Update the session manager config file to load the modules via the
config now. Rename the session modules section to another name.
Update pipewire-pulse to also load a specific pulse property file.
This then makes it pssible to assign specific RT priorities for the
pipewire-pulse process.
Set initial device profile according to what's connected at startup,
rather than having media-session try to set it to A2DP (and fail, if the
profile was not connected, resulting to startup in null profile).
This avoids making a codec switch at device startup (we'll stay with
what BlueZ autoconnected us to, usually the previously used codec).