The pw_remote object is really a wrapper around the pw_core_proxy.
The events it emits are also available in the core proxy and are
generally awkward to use.
With some clever new pw_core_proxy_* methods and a pw_core_connect
to create the core_proxy, we can convert all code away from pw_remote.
This is a first step in this conversion, using the pw_remote behind
the scenes. It leaks into some places because it really needs to become
its own struct in a next step.
Make the connection as soon as we create the client. We create it
without file descriptor and then set it when we connect. This
makes it possible to use the connection to queue messages before
we connect.
media-session: Wait for devices to appear and be bound before setting
the profile on the device. Then wait for all the nodes to appear
before attempting the create endpoints on the device.
Pass the client.id that we made this endpoint for in the endpoint
properties. This makes it possible to let pulse find the client
that belongs to the endpiont. The client.id is used to find the
client that actually made the object (the session manager)
Create an endpoint link object when linking endpoints. Keep track
of the links in the endpoint_link and cleanup when they are all
gone.
Improve properties on session objects.
Create a helper in the session manager to link all ports between
2 nodes.
Make the output endpoint call the input endpoint create_link, passing
the node or ports to link to.
Make the input endpoint complete the link by calling the session
helper to link all ports.
Remove the node policy, we're only using a policy for the endpoints
now.
pulseaudio card is mapped to device
pulseaudio sink/source is mapped to an endpoint
prepare to map streams to card profiles
Add Route param to implement the endpoint routing later (ports)
Create an alsa endpoint for each device
Create one stream for each endpoint (Playback/Capture)
Implement create_link on the endpoint. The idea is to call
create link on the peer endpoint to complete the link. Remove
create_link on the session.
Add stream-monitor to turn pw_stream nodes into endpoints
Add a policy manager that tries to link endpoints
Use enum pw_direction for the endpoint direction. We can use the
media_class to determine if this is a pw_stream or not but it should
not really matter, you can link any output to any input.
Add autoconnect property for endpoints to make the policy connect.
Make it possible to know when a proxy is bound to a global id before
the global shows up in the registry. This makes it possible to match
locally created objects to the one appearing in the registry and
possibly avoid a second bind.
Bind to the resource in create_object before we register the global.
This ensure a client gets to see the resource global id associated
with the resource before it appears in the registry, which makes it
easier to patch the local proxy to the global object.
Don't register in client_new() to make it possible to do other things
on the client before registering. Register the client in protocol-native
after we set up the events etc.
otherwise, if the access module blocks the client, the on_start
callback in the protocol is not called and there is no global,
which means the session manager cannot do anything to grant
permissions on this client and the client is blocked forever
Separate the session manager in a monitor and policy part.
The monitor manages the devices and endpoints.
The policy watches the nodes/ports/clients and applies the policy
of linking them.
Because both now have a separate connection, we can remove some
hacks in the protocol. When a remote was both the implementer and
user of an object we could get in a deadlock when the user was
blocked waiting and the implementator was blocked sending a reply.
We used to un-busy a client when it was expecting a reply from a
ping or sync for this reason.
Add and use some more keys for the endpoints and streams.
Metadata allows apps to attach properties to objects that can be
read by other apps.
Not complete yet, properties should be removed when the object is
removed.
For flatpaks we need to be able to support older v0 protocol clients.
To handle this we have:
- the connection detects an old client when it receives the first
message. It can do this by checking the sequence number, on old
versions it contains the message size and is never 0, on new
clients the sequence number is 0.
- We add a new signal at the start of the connection with the detected
version number. This installs the right version of the core proxy.
We also move the binding of the client until the hello message is
received. This way we can have a new client connect (portal),
hand over the connection to an old client, which then removes the
client binding again in the hello request with a v0 version.
There are some changes to the passing of fds in v0 vs v3 which need
to investigated some more.
- bump version of our interfaces to 3. This makes it possible to
have v0 and v3 protocol marshal functions.
- Add version number in the proxy. This is mostly automatically done
internally based on the version numbers the library is compiled
with. Where the version number was in the API before, it is now
actually used to look up the right protocol marshal functions. For
Proxies there is usually just 1 version, the current one. It is the
server that will support different versions.
- Add v0 compat marshal functions to convert from and to v0 format.
This has some complications. v0 has a type map it keeps in sync
with the server. For this we have a static type map with mappings
to our own v3 types. Pods are mostly the same except for objects
that used to have arbitrary pods in v0 vs spa_pod_prop in v3. Also
convert between v0 spa_pod_prop and v3 spa_pod_choice.
Formats and commands are also slightly different so handle those
mappings as well.
We only have marshal functions for the server side (resource)
v0 functions.
- Add v0 compatible client-node again. It's a bit tricky to map, v0
client-node basically lets the server to the mixing and teeing
and just does the processing of the internal node.
When the port receives a format, look if we can find a mixer for it
and configure it.
Use the float32 mono mixer when possible.
Use the new pw_buffers in the link.
Let the port allocate buffers between the mixer and node when
requested.
The client-node doesn't need a mixer because mixing is done on the
client.
Remove all mixer and buffer negotiation code from adapter because
it is now done at the port level.