mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Move subscription signal to context
Emit the subscription signal event directly from the context, This is easier and it avoids having two subscribe objects. Remove client proxy property from the context, we don't need it anymore. Only expose objects when the client manager has a name-owner.
This commit is contained in:
		
							parent
							
								
									2b1558d0e5
								
							
						
					
					
						commit
						e151150cad
					
				
					 4 changed files with 115 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -40,7 +40,7 @@ struct _PvContextPrivate
 | 
			
		|||
 | 
			
		||||
  PvClient1 *client;
 | 
			
		||||
 | 
			
		||||
  PvSubscribe *internal_subscribe;
 | 
			
		||||
  PvSubscriptionFlags subscription_mask;
 | 
			
		||||
  PvSubscribe *subscribe;
 | 
			
		||||
 | 
			
		||||
  GList *sources;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,9 +69,17 @@ enum
 | 
			
		|||
  PROP_PROPERTIES,
 | 
			
		||||
  PROP_STATE,
 | 
			
		||||
  PROP_CONNECTION,
 | 
			
		||||
  PROP_CLIENT_PROXY
 | 
			
		||||
  PROP_SUBSCRIPTION_MASK,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  SIGNAL_SUBSCRIPTION_EVENT,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pv_context_get_property (GObject    *_object,
 | 
			
		||||
                         guint       prop_id,
 | 
			
		||||
| 
						 | 
				
			
			@ -98,8 +106,8 @@ pv_context_get_property (GObject    *_object,
 | 
			
		|||
      g_value_set_object (value, priv->connection);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_CLIENT_PROXY:
 | 
			
		||||
      g_value_set_object (value, priv->client);
 | 
			
		||||
    case PROP_SUBSCRIPTION_MASK:
 | 
			
		||||
      g_value_set_flags (value, priv->subscription_mask);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +137,10 @@ pv_context_set_property (GObject      *_object,
 | 
			
		|||
      priv->properties = g_value_dup_variant (value);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case PROP_SUBSCRIPTION_MASK:
 | 
			
		||||
      priv->subscription_mask = g_value_get_flags (value);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (context, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
| 
						 | 
				
			
			@ -213,18 +225,41 @@ pv_context_class_init (PvContextClass * klass)
 | 
			
		|||
                                                        G_PARAM_READABLE |
 | 
			
		||||
                                                        G_PARAM_STATIC_STRINGS));
 | 
			
		||||
  /**
 | 
			
		||||
   * PvContext:client-path
 | 
			
		||||
   * PvContext:subscription-mask
 | 
			
		||||
   *
 | 
			
		||||
   * The client object path of the context.
 | 
			
		||||
   * The subscription mask
 | 
			
		||||
   */
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
                                   PROP_CLIENT_PROXY,
 | 
			
		||||
                                   g_param_spec_object ("client-proxy",
 | 
			
		||||
                                                        "Client Proxy",
 | 
			
		||||
                                                        "The client proxy",
 | 
			
		||||
                                                        G_TYPE_DBUS_PROXY,
 | 
			
		||||
                                                        G_PARAM_READABLE |
 | 
			
		||||
                                   PROP_SUBSCRIPTION_MASK,
 | 
			
		||||
                                   g_param_spec_flags ("subscription-mask",
 | 
			
		||||
                                                       "Subscription Mask",
 | 
			
		||||
                                                       "The object to receive subscription events of",
 | 
			
		||||
                                                       PV_TYPE_SUBSCRIPTION_FLAGS,
 | 
			
		||||
                                                       0,
 | 
			
		||||
                                                       G_PARAM_READWRITE |
 | 
			
		||||
                                                       G_PARAM_STATIC_STRINGS));
 | 
			
		||||
  /**
 | 
			
		||||
   * PvContext:subscription-event
 | 
			
		||||
   * @subscribe: The #PvContext emitting the signal.
 | 
			
		||||
   * @event: A #PvSubscriptionEvent
 | 
			
		||||
   * @flags: #PvSubscriptionFlags indicating the object
 | 
			
		||||
   * @object: the GDBusProxy object
 | 
			
		||||
   *
 | 
			
		||||
   * Notify about a new object that was added/removed/modified.
 | 
			
		||||
   */
 | 
			
		||||
  signals[SIGNAL_SUBSCRIPTION_EVENT] = g_signal_new ("subscription-event",
 | 
			
		||||
                                                     G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                                                     G_SIGNAL_RUN_LAST,
 | 
			
		||||
                                                     0,
 | 
			
		||||
                                                     NULL,
 | 
			
		||||
                                                     NULL,
 | 
			
		||||
                                                     g_cclosure_marshal_generic,
 | 
			
		||||
                                                     G_TYPE_NONE,
 | 
			
		||||
                                                     3,
 | 
			
		||||
                                                     PV_TYPE_SUBSCRIPTION_EVENT,
 | 
			
		||||
                                                     PV_TYPE_SUBSCRIPTION_FLAGS,
 | 
			
		||||
                                                     G_TYPE_DBUS_PROXY);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -234,10 +269,10 @@ pv_context_init (PvContext * context)
 | 
			
		|||
 | 
			
		||||
  priv->state = PV_CONTEXT_STATE_UNCONNECTED;
 | 
			
		||||
  priv->server_manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX);
 | 
			
		||||
  priv->internal_subscribe = pv_subscribe_new ();
 | 
			
		||||
  g_object_set (priv->internal_subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL);
 | 
			
		||||
  g_signal_connect (priv->internal_subscribe, "subscription-event", (GCallback) subscription_cb, context);
 | 
			
		||||
  g_signal_connect (priv->internal_subscribe, "notify::state", (GCallback) subscription_state, context);
 | 
			
		||||
  priv->subscribe = pv_subscribe_new ();
 | 
			
		||||
  g_object_set (priv->subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL);
 | 
			
		||||
  g_signal_connect (priv->subscribe, "subscription-event", (GCallback) subscription_cb, context);
 | 
			
		||||
  g_signal_connect (priv->subscribe, "notify::state", (GCallback) subscription_state, context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -362,6 +397,15 @@ subscription_cb (PvSubscribe         *subscribe,
 | 
			
		|||
    case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (flags & priv->subscription_mask)
 | 
			
		||||
    g_signal_emit (context,
 | 
			
		||||
                   signals[SIGNAL_SUBSCRIPTION_EVENT],
 | 
			
		||||
                   0,
 | 
			
		||||
                   event,
 | 
			
		||||
                   flags,
 | 
			
		||||
                   object);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -373,7 +417,6 @@ subscription_state (GObject    *object,
 | 
			
		|||
  PvSubscriptionState state;
 | 
			
		||||
 | 
			
		||||
  g_object_get (object, "state", &state, NULL);
 | 
			
		||||
 | 
			
		||||
  g_print ("got subscription state %d\n", state);
 | 
			
		||||
 | 
			
		||||
  switch (state) {
 | 
			
		||||
| 
						 | 
				
			
			@ -399,12 +442,8 @@ on_name_appeared (GDBusConnection *connection,
 | 
			
		|||
  priv->connection = connection;
 | 
			
		||||
  g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
 | 
			
		||||
 | 
			
		||||
  if (priv->subscribe) {
 | 
			
		||||
  g_object_set (priv->subscribe, "connection", priv->connection,
 | 
			
		||||
                                 "service", name, NULL);
 | 
			
		||||
  }
 | 
			
		||||
  g_object_set (priv->internal_subscribe, "connection", priv->connection,
 | 
			
		||||
                                          "service", name, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -418,11 +457,8 @@ on_name_vanished (GDBusConnection *connection,
 | 
			
		|||
  priv->connection = connection;
 | 
			
		||||
  g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
 | 
			
		||||
 | 
			
		||||
  if (priv->subscribe)
 | 
			
		||||
  g_object_set (priv->subscribe, "connection", connection, NULL);
 | 
			
		||||
 | 
			
		||||
  g_object_set (priv->internal_subscribe, "connection", connection, NULL);
 | 
			
		||||
 | 
			
		||||
  if (priv->flags & PV_CONTEXT_FLAGS_NOFAIL) {
 | 
			
		||||
    context_set_state (context, PV_CONTEXT_STATE_CONNECTING);
 | 
			
		||||
  } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -430,37 +466,6 @@ on_name_vanished (GDBusConnection *connection,
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pv_context_set_subscribe:
 | 
			
		||||
 * @context: a #PvContext
 | 
			
		||||
 * @subscribe: (transfer full): a #PvSubscribe
 | 
			
		||||
 *
 | 
			
		||||
 * Use @subscribe to receive subscription events from @context.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE on success.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe)
 | 
			
		||||
{
 | 
			
		||||
  PvContextPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
 | 
			
		||||
 | 
			
		||||
  priv = context->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->subscribe)
 | 
			
		||||
    g_object_unref (priv->subscribe);
 | 
			
		||||
  priv->subscribe = subscribe;
 | 
			
		||||
 | 
			
		||||
  if (priv->subscribe && priv->connection) {
 | 
			
		||||
    g_object_set (priv->subscribe, "connection", priv->connection,
 | 
			
		||||
                                   "service", PV_DBUS_SERVICE, NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pv_context_connect:
 | 
			
		||||
 * @context: a #PvContext
 | 
			
		||||
| 
						 | 
				
			
			@ -623,23 +628,6 @@ pv_context_get_connection (PvContext *context)
 | 
			
		|||
  return context->priv->connection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pv_context_get_client_proxy:
 | 
			
		||||
 * @context: a #PvContext
 | 
			
		||||
 *
 | 
			
		||||
 * Get the client proxy that @context is registered with
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the client proxy of @context or %NULL when not
 | 
			
		||||
 * registered.
 | 
			
		||||
 */
 | 
			
		||||
GDBusProxy *
 | 
			
		||||
pv_context_get_client_proxy (PvContext *context)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (PV_IS_CONTEXT (context), NULL);
 | 
			
		||||
 | 
			
		||||
  return G_DBUS_PROXY (context->priv->client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GDBusProxy *
 | 
			
		||||
pv_context_find_source (PvContext *context, const gchar *name, GVariant *props)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,8 +100,6 @@ GType             pv_context_get_type              (void);
 | 
			
		|||
 | 
			
		||||
PvContext *       pv_context_new                   (const gchar *name, GVariant *properties);
 | 
			
		||||
 | 
			
		||||
gboolean          pv_context_set_subscribe         (PvContext *context, PvSubscribe *subscribe);
 | 
			
		||||
 | 
			
		||||
gboolean          pv_context_connect               (PvContext *context, PvContextFlags flags);
 | 
			
		||||
gboolean          pv_context_disconnect            (PvContext *context);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +109,6 @@ gboolean          pv_context_unregister_source     (PvContext *context, PvSource
 | 
			
		|||
PvContextState    pv_context_get_state             (PvContext *context);
 | 
			
		||||
 | 
			
		||||
GDBusConnection * pv_context_get_connection        (PvContext *context);
 | 
			
		||||
GDBusProxy *      pv_context_get_client_proxy      (PvContext *context);
 | 
			
		||||
 | 
			
		||||
GDBusProxy *      pv_context_find_source           (PvContext *context, const gchar *name, GVariant *props);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -363,11 +363,57 @@ on_client_manager_signal (GDBusObjectManagerClient *manager,
 | 
			
		|||
  g_print ("proxy signal %s\n", signal_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_manager_appeared (PvSubscribe *subscribe)
 | 
			
		||||
{
 | 
			
		||||
  PvSubscribePrivate *priv = subscribe->priv;
 | 
			
		||||
  GList *objects, *walk;
 | 
			
		||||
 | 
			
		||||
  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager));
 | 
			
		||||
  for (walk = objects; walk ; walk = g_list_next (walk)) {
 | 
			
		||||
    on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager),
 | 
			
		||||
                                    walk->data,
 | 
			
		||||
                                    subscribe);
 | 
			
		||||
  }
 | 
			
		||||
  if (--priv->pending_subscribes == 0)
 | 
			
		||||
    subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
client_manager_disappeared (PvSubscribe *subscribe)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_client_manager_name_owner (GObject    *object,
 | 
			
		||||
                              GParamSpec *pspec,
 | 
			
		||||
                              gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  PvSubscribe *subscribe = user_data;
 | 
			
		||||
  PvSubscribePrivate *priv = subscribe->priv;
 | 
			
		||||
  gchar *name_owner;
 | 
			
		||||
 | 
			
		||||
  g_object_get (priv->client_manager, "name-owner", &name_owner, NULL);
 | 
			
		||||
  g_print ("client manager %s %s\n",
 | 
			
		||||
      g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)),
 | 
			
		||||
      name_owner);
 | 
			
		||||
 | 
			
		||||
  if (name_owner) {
 | 
			
		||||
    client_manager_appeared (subscribe);
 | 
			
		||||
    g_free (name_owner);
 | 
			
		||||
  } else {
 | 
			
		||||
    client_manager_disappeared (subscribe);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
connect_client_signals (PvSubscribe *subscribe)
 | 
			
		||||
{
 | 
			
		||||
  PvSubscribePrivate *priv = subscribe->priv;
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (priv->client_manager, "notify::name-owner",
 | 
			
		||||
      (GCallback) on_client_manager_name_owner, subscribe);
 | 
			
		||||
  g_signal_connect (priv->client_manager, "interface-added",
 | 
			
		||||
      (GCallback) on_client_manager_interface_added, subscribe);
 | 
			
		||||
  g_signal_connect (priv->client_manager, "interface-removed",
 | 
			
		||||
| 
						 | 
				
			
			@ -390,27 +436,14 @@ on_client_manager_ready (GObject *source_object,
 | 
			
		|||
  PvSubscribe *subscribe = user_data;
 | 
			
		||||
  PvSubscribePrivate *priv = subscribe->priv;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  GList *objects, *walk;
 | 
			
		||||
 | 
			
		||||
  priv->client_manager = pv_object_manager_client_new_finish (res, &error);
 | 
			
		||||
  if (priv->client_manager == NULL)
 | 
			
		||||
    goto manager_error;
 | 
			
		||||
 | 
			
		||||
  g_print ("client manager %s %s\n",
 | 
			
		||||
      g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)),
 | 
			
		||||
      g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)));
 | 
			
		||||
 | 
			
		||||
  connect_client_signals (subscribe);
 | 
			
		||||
 | 
			
		||||
  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager));
 | 
			
		||||
  for (walk = objects; walk ; walk = g_list_next (walk)) {
 | 
			
		||||
    on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager),
 | 
			
		||||
                                    walk->data,
 | 
			
		||||
                                    subscribe);
 | 
			
		||||
  }
 | 
			
		||||
  if (--priv->pending_subscribes == 0)
 | 
			
		||||
    subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY);
 | 
			
		||||
 | 
			
		||||
  on_client_manager_name_owner (G_OBJECT (priv->client_manager), NULL, subscribe);
 | 
			
		||||
  return;
 | 
			
		||||
 | 
			
		||||
  /* ERRORS */
 | 
			
		||||
| 
						 | 
				
			
			@ -498,6 +531,7 @@ pv_subscribe_set_property (GObject      *_object,
 | 
			
		|||
      if (priv->connection)
 | 
			
		||||
        g_object_unref (priv->connection);
 | 
			
		||||
      priv->connection = g_value_dup_object (value);
 | 
			
		||||
      if (priv->connection)
 | 
			
		||||
        install_subscription (subscribe);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,12 +69,8 @@ on_state_notify (GObject    *gobject,
 | 
			
		|||
      break;
 | 
			
		||||
    case PV_CONTEXT_STATE_READY:
 | 
			
		||||
    {
 | 
			
		||||
      PvSubscribe *subscribe;
 | 
			
		||||
 | 
			
		||||
      subscribe = pv_subscribe_new ();
 | 
			
		||||
      g_object_set (subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL);
 | 
			
		||||
      g_signal_connect (subscribe, "subscription-event", (GCallback) subscription_cb, NULL);
 | 
			
		||||
      pv_context_set_subscribe (c, subscribe);
 | 
			
		||||
      g_object_set (c, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL);
 | 
			
		||||
      g_signal_connect (c, "subscription-event", (GCallback) subscription_cb, NULL);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue