mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-07 13:30:09 -05:00
handle remote and local sources better
Track remote and local sources separately and make SourceProvider1 interfaces for remote objects so that we get the subscription right. Move disconnect from the Manager1 to Client1 interface and implement in the context.
This commit is contained in:
parent
93c246c4ce
commit
09de2d3db9
12 changed files with 184 additions and 70 deletions
|
|
@ -180,20 +180,20 @@ client_register_object (PvClient *client, const gchar *prefix)
|
|||
{
|
||||
PvClientPrivate *priv = client->priv;
|
||||
PvDaemon *daemon = priv->daemon;
|
||||
GDBusObjectSkeleton *skel;
|
||||
PvObjectSkeleton *skel;
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf ("%s/client", prefix);
|
||||
skel = g_dbus_object_skeleton_new (name);
|
||||
skel = pv_object_skeleton_new (name);
|
||||
g_free (name);
|
||||
|
||||
priv->client1 = pv_client1_skeleton_new ();
|
||||
pv_client1_set_name (priv->client1, "poppy");
|
||||
g_signal_connect (priv->client1, "handle-create-source-output", (GCallback) handle_create_source_output, client);
|
||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (priv->client1));
|
||||
pv_object_skeleton_set_client1 (skel, priv->client1);
|
||||
|
||||
g_free (priv->object_path);
|
||||
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
|
||||
priv->object_path = pv_daemon_export_uniquely (daemon, G_DBUS_OBJECT_SKELETON (skel));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct _PvDaemonPrivate
|
|||
guint id;
|
||||
GDBusConnection *connection;
|
||||
GDBusObjectManagerServer *server_manager;
|
||||
PvSubscribe *subscribe;
|
||||
|
||||
GHashTable *senders;
|
||||
GList *sources;
|
||||
|
|
@ -52,33 +53,32 @@ typedef struct {
|
|||
} SenderData;
|
||||
|
||||
static void
|
||||
on_subscription_event (PvSubscribe *subscribe,
|
||||
PvSubscriptionEvent event,
|
||||
PvSubscriptionFlags flags,
|
||||
GDBusObjectProxy *object,
|
||||
gpointer user_data)
|
||||
on_server_subscription_event (PvSubscribe *subscribe,
|
||||
PvSubscriptionEvent event,
|
||||
PvSubscriptionFlags flags,
|
||||
GDBusObjectProxy *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
SenderData *data = user_data;
|
||||
PvDaemon *daemon = data->daemon;
|
||||
PvDaemon *daemon = user_data;
|
||||
PvDaemonPrivate *priv = daemon->priv;
|
||||
const gchar *object_path;
|
||||
PvSource1 *source1;
|
||||
|
||||
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
||||
|
||||
g_print ("got event %d %d %s.%s\n", event, flags, data->sender, object_path);
|
||||
gchar *service;
|
||||
|
||||
if (flags != PV_SUBSCRIPTION_FLAGS_SOURCE)
|
||||
return;
|
||||
|
||||
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
||||
|
||||
g_object_get (subscribe, "service", &service, NULL);
|
||||
g_print ("got event %d %d %s.%s\n", event, flags, service, object_path);
|
||||
|
||||
source1 = pv_object_peek_source1 (PV_OBJECT (object));
|
||||
|
||||
switch (event) {
|
||||
case PV_SUBSCRIPTION_EVENT_NEW:
|
||||
{
|
||||
g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", data->sender);
|
||||
|
||||
g_hash_table_insert (data->sources, g_strdup (object_path), source1);
|
||||
g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", service);
|
||||
priv->sources = g_list_prepend (priv->sources, source1);
|
||||
break;
|
||||
}
|
||||
|
|
@ -89,12 +89,49 @@ on_subscription_event (PvSubscribe *subscribe,
|
|||
case PV_SUBSCRIPTION_EVENT_REMOVE:
|
||||
{
|
||||
priv->sources = g_list_remove (priv->sources, source1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_sender_subscription_event (PvSubscribe *subscribe,
|
||||
PvSubscriptionEvent event,
|
||||
PvSubscriptionFlags flags,
|
||||
GDBusObjectProxy *object,
|
||||
gpointer user_data)
|
||||
{
|
||||
SenderData *data = user_data;
|
||||
PvDaemon *daemon = data->daemon;
|
||||
const gchar *object_path;
|
||||
|
||||
on_server_subscription_event (subscribe, event, flags, object, daemon);
|
||||
|
||||
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
||||
|
||||
switch (event) {
|
||||
case PV_SUBSCRIPTION_EVENT_NEW:
|
||||
{
|
||||
PvSourceProvider *provider;
|
||||
|
||||
provider = pv_source_provider_new (daemon, PV_DBUS_OBJECT_PREFIX, data->sender,
|
||||
object_path);
|
||||
g_hash_table_insert (data->sources, g_strdup (object_path), provider);
|
||||
break;
|
||||
}
|
||||
|
||||
case PV_SUBSCRIPTION_EVENT_CHANGE:
|
||||
break;
|
||||
|
||||
case PV_SUBSCRIPTION_EVENT_REMOVE:
|
||||
{
|
||||
g_hash_table_remove (data->sources, object_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
client_name_appeared_handler (GDBusConnection *connection,
|
||||
const gchar *name,
|
||||
|
|
@ -113,7 +150,7 @@ client_name_appeared_handler (GDBusConnection *connection,
|
|||
|
||||
g_signal_connect (data->subscribe,
|
||||
"subscription-event",
|
||||
(GCallback) on_subscription_event,
|
||||
(GCallback) on_sender_subscription_event,
|
||||
data);
|
||||
}
|
||||
|
||||
|
|
@ -192,50 +229,25 @@ handle_connect_client (PvDaemon1 *interface,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
handle_disconnect_client (PvDaemon1 *interface,
|
||||
GDBusMethodInvocation *invocation,
|
||||
const gchar *arg_client,
|
||||
gpointer user_data)
|
||||
{
|
||||
PvDaemon *daemon = user_data;
|
||||
PvDaemonPrivate *priv = daemon->priv;
|
||||
const gchar *sender;
|
||||
SenderData *data;
|
||||
|
||||
sender = g_dbus_method_invocation_get_sender (invocation);
|
||||
|
||||
g_print ("disconnect client %s\n", sender);
|
||||
data = g_hash_table_lookup (priv->senders, sender);
|
||||
if (data != NULL) {
|
||||
g_hash_table_remove (data->clients, arg_client);
|
||||
}
|
||||
|
||||
pv_daemon1_complete_disconnect_client (interface, invocation);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
export_server_object (PvDaemon *daemon, GDBusObjectManagerServer *manager)
|
||||
{
|
||||
GDBusObjectSkeleton *skel;
|
||||
PvObjectSkeleton *skel;
|
||||
|
||||
skel = g_dbus_object_skeleton_new (PV_DBUS_OBJECT_SERVER);
|
||||
skel = pv_object_skeleton_new (PV_DBUS_OBJECT_SERVER);
|
||||
{
|
||||
PvDaemon1 *iface;
|
||||
|
||||
iface = pv_daemon1_skeleton_new ();
|
||||
g_signal_connect (iface, "handle-connect-client", (GCallback) handle_connect_client, daemon);
|
||||
g_signal_connect (iface, "handle-disconnect-client", (GCallback) handle_disconnect_client, daemon);
|
||||
pv_daemon1_set_user_name (iface, g_get_user_name ());
|
||||
pv_daemon1_set_host_name (iface, g_get_host_name ());
|
||||
pv_daemon1_set_version (iface, PACKAGE_VERSION);
|
||||
pv_daemon1_set_name (iface, PACKAGE_NAME);
|
||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
||||
pv_object_skeleton_set_daemon1 (skel, iface);
|
||||
g_object_unref (iface);
|
||||
}
|
||||
g_dbus_object_manager_server_export (manager, skel);
|
||||
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (skel));
|
||||
g_object_unref (skel);
|
||||
}
|
||||
|
||||
|
|
@ -257,10 +269,16 @@ name_acquired_handler (GDBusConnection *connection,
|
|||
{
|
||||
PvDaemon *daemon = user_data;
|
||||
PvDaemonPrivate *priv = daemon->priv;
|
||||
GDBusObjectManagerServer *manager;
|
||||
GDBusObjectManagerServer *manager = priv->server_manager;
|
||||
|
||||
g_object_set (priv->subscribe, "service", PV_DBUS_SERVICE,
|
||||
"subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE,
|
||||
"connection", connection,
|
||||
NULL);
|
||||
|
||||
|
||||
priv->server_manager = manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX);
|
||||
export_server_object (daemon, manager);
|
||||
|
||||
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||
}
|
||||
|
||||
|
|
@ -273,8 +291,10 @@ name_lost_handler (GDBusConnection *connection,
|
|||
PvDaemonPrivate *priv = daemon->priv;
|
||||
GDBusObjectManagerServer *manager = priv->server_manager;
|
||||
|
||||
g_object_set (priv->subscribe, "connection", connection, NULL);
|
||||
|
||||
g_dbus_object_manager_server_unexport (manager, PV_DBUS_OBJECT_SERVER);
|
||||
g_clear_object (&priv->server_manager);
|
||||
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||
}
|
||||
|
||||
PvDaemon *
|
||||
|
|
@ -334,6 +354,27 @@ pv_daemon_unexport (PvDaemon *daemon, const gchar *object_path)
|
|||
g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path);
|
||||
}
|
||||
|
||||
void
|
||||
pv_daemon_add_source (PvDaemon *daemon, PvSource *source)
|
||||
{
|
||||
PvDaemonPrivate *priv;
|
||||
|
||||
g_return_if_fail (PV_IS_DAEMON (daemon));
|
||||
g_return_if_fail (PV_IS_SOURCE (source));
|
||||
priv = daemon->priv;
|
||||
|
||||
pv_source_set_manager (source, priv->server_manager);
|
||||
}
|
||||
|
||||
void
|
||||
pv_daemon_remove_source (PvDaemon *daemon, PvSource *source)
|
||||
{
|
||||
g_return_if_fail (PV_IS_DAEMON (daemon));
|
||||
g_return_if_fail (PV_IS_SOURCE (source));
|
||||
|
||||
pv_source_set_manager (source, NULL);
|
||||
}
|
||||
|
||||
PvSource1 *
|
||||
pv_daemon_get_source (PvDaemon *daemon, const gchar *name)
|
||||
{
|
||||
|
|
@ -359,6 +400,7 @@ pv_daemon_finalize (GObject * object)
|
|||
PvDaemon *daemon = PV_DAEMON_CAST (object);
|
||||
PvDaemonPrivate *priv = daemon->priv;
|
||||
|
||||
g_clear_object (&priv->server_manager);
|
||||
g_hash_table_unref (priv->senders);
|
||||
pv_daemon_stop (daemon);
|
||||
|
||||
|
|
@ -381,5 +423,12 @@ pv_daemon_init (PvDaemon * daemon)
|
|||
PvDaemonPrivate *priv = daemon->priv = PV_DAEMON_GET_PRIVATE (daemon);
|
||||
|
||||
priv->senders = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
priv->server_manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX);
|
||||
|
||||
priv->subscribe = pv_subscribe_new ();
|
||||
g_signal_connect (priv->subscribe,
|
||||
"subscription-event",
|
||||
(GCallback) on_server_subscription_event,
|
||||
daemon);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ void pv_daemon_stop (PvDaemon *daemon);
|
|||
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
|
||||
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
|
||||
|
||||
void pv_daemon_add_source (PvDaemon *daemon, PvSource *source);
|
||||
void pv_daemon_remove_source (PvDaemon *daemon, PvSource *source);
|
||||
|
||||
PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -113,11 +113,11 @@ source_provider_register_object (PvSourceProvider *client, const gchar *prefix)
|
|||
{
|
||||
PvSourceProviderPrivate *priv = client->priv;
|
||||
PvDaemon *daemon = priv->daemon;
|
||||
GDBusObjectSkeleton *skel;
|
||||
PvObjectSkeleton *skel;
|
||||
gchar *name;
|
||||
|
||||
name = g_strdup_printf ("%s/source", prefix);
|
||||
skel = g_dbus_object_skeleton_new (name);
|
||||
skel = pv_object_skeleton_new (name);
|
||||
g_free (name);
|
||||
|
||||
{
|
||||
|
|
@ -126,12 +126,12 @@ source_provider_register_object (PvSourceProvider *client, const gchar *prefix)
|
|||
iface = pv_source_provider1_skeleton_new ();
|
||||
g_object_set (iface, "name", priv->name, NULL);
|
||||
g_object_set (iface, "path", priv->path, NULL);
|
||||
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
|
||||
pv_object_skeleton_set_source_provider1 (skel, iface);
|
||||
g_object_unref (iface);
|
||||
}
|
||||
|
||||
g_free (priv->object_path);
|
||||
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
|
||||
priv->object_path = pv_daemon_export_uniquely (daemon, G_DBUS_OBJECT_SKELETON (skel));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue