mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-02-03 20:50:30 +01:00
global-proxy: delay object creation until bound feature is requested
Allows handling errors if creation fails
This commit is contained in:
parent
b8030e138d
commit
8fdd99d956
4 changed files with 99 additions and 56 deletions
|
|
@ -182,20 +182,11 @@ wp_device_new_from_factory (WpCore * core,
|
|||
const gchar * factory_name, WpProperties * properties)
|
||||
{
|
||||
g_autoptr (WpProperties) props = properties;
|
||||
WpDevice *self = NULL;
|
||||
struct pw_core *pw_core = wp_core_get_pw_core (core);
|
||||
|
||||
if (G_UNLIKELY (!pw_core)) {
|
||||
g_critical ("The WirePlumber core is not connected; "
|
||||
"device cannot be created");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_object_new (WP_TYPE_DEVICE, "core", core, NULL);
|
||||
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_create_object (pw_core,
|
||||
factory_name, PW_TYPE_INTERFACE_Device, PW_VERSION_DEVICE,
|
||||
props ? wp_properties_peek_dict (props) : NULL, 0));
|
||||
return self;
|
||||
return g_object_new (WP_TYPE_DEVICE,
|
||||
"core", core,
|
||||
"factory-name", factory_name,
|
||||
"global-properties", props,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,13 +22,16 @@ typedef struct _WpGlobalProxyPrivate WpGlobalProxyPrivate;
|
|||
struct _WpGlobalProxyPrivate
|
||||
{
|
||||
WpGlobal *global;
|
||||
gchar factory_name[96];
|
||||
WpProperties *properties;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_GLOBAL,
|
||||
PROP_PERMISSIONS,
|
||||
PROP_FACTORY_NAME,
|
||||
PROP_GLOBAL_PROPERTIES,
|
||||
PROP_PERMISSIONS,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -64,6 +67,7 @@ wp_global_proxy_finalize (GObject * object)
|
|||
WpGlobalProxyPrivate *priv =
|
||||
wp_global_proxy_get_instance_private (self);
|
||||
|
||||
g_clear_pointer (&priv->properties, wp_properties_unref);
|
||||
g_clear_pointer (&priv->global, wp_global_unref);
|
||||
|
||||
G_OBJECT_CLASS (wp_global_proxy_parent_class)->finalize (object);
|
||||
|
|
@ -81,6 +85,14 @@ wp_global_proxy_set_property (GObject * object, guint property_id,
|
|||
case PROP_GLOBAL:
|
||||
priv->global = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_FACTORY_NAME:
|
||||
priv->factory_name[0] = '\0';
|
||||
strncpy (priv->factory_name, g_value_get_string (value),
|
||||
sizeof (priv->factory_name) - 1);
|
||||
break;
|
||||
case PROP_GLOBAL_PROPERTIES:
|
||||
priv->properties = g_value_dup_boxed (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
|
|
@ -129,23 +141,72 @@ wp_global_proxy_activate_get_next_step (WpObject * object,
|
|||
return STEP_BIND;
|
||||
}
|
||||
|
||||
static void
|
||||
wp_global_proxy_step_bind (WpObject * object,
|
||||
WpFeatureActivationTransition * transition, guint step,
|
||||
WpObjectFeatures missing)
|
||||
{
|
||||
WpProxyClass *proxy_klass = WP_PROXY_GET_CLASS (WP_PROXY (object));
|
||||
WpGlobalProxy *self = WP_GLOBAL_PROXY (object);
|
||||
WpGlobalProxyPrivate *priv = wp_global_proxy_get_instance_private (self);
|
||||
|
||||
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
|
||||
|
||||
/* Create the pipewire object if global is NULL */
|
||||
if (priv->global == NULL && priv->factory_name[0] != '\0') {
|
||||
g_autoptr (WpCore) core = NULL;
|
||||
struct pw_core *pw_core = NULL;
|
||||
struct pw_proxy * p = NULL;
|
||||
|
||||
core = wp_object_get_core (WP_OBJECT (self));
|
||||
if (G_UNLIKELY (!core)) {
|
||||
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"The WirePlumber core is not valid; object cannot be created"));
|
||||
return;
|
||||
}
|
||||
|
||||
pw_core = wp_core_get_pw_core (core);
|
||||
if (G_UNLIKELY (!pw_core)) {
|
||||
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"The WirePlumber core is not connected; object cannot be created"));
|
||||
return;
|
||||
}
|
||||
|
||||
p = pw_core_create_object (pw_core, priv->factory_name,
|
||||
proxy_klass->pw_iface_type, proxy_klass->pw_iface_version,
|
||||
priv->properties ?
|
||||
wp_properties_peek_dict (priv->properties) : NULL, 0);
|
||||
if (G_UNLIKELY (!p)) {
|
||||
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED,
|
||||
"Failed to create object with given factory name and properties"));
|
||||
return;
|
||||
}
|
||||
|
||||
wp_proxy_set_pw_proxy (WP_PROXY (self), p);
|
||||
}
|
||||
|
||||
/* Bind */
|
||||
if (wp_proxy_get_pw_proxy (WP_PROXY (self)) == NULL) {
|
||||
if (!wp_global_proxy_bind (self)) {
|
||||
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"No global specified; cannot bind proxy"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wp_global_proxy_activate_execute_step (WpObject * object,
|
||||
WpFeatureActivationTransition * transition, guint step,
|
||||
WpObjectFeatures missing)
|
||||
{
|
||||
WpGlobalProxy *self = WP_GLOBAL_PROXY (object);
|
||||
|
||||
switch (step) {
|
||||
case STEP_BIND:
|
||||
wp_proxy_watch_bind_error (WP_PROXY (self), WP_TRANSITION (transition));
|
||||
if (wp_proxy_get_pw_proxy (WP_PROXY (self)) == NULL) {
|
||||
if (!wp_global_proxy_bind (self)) {
|
||||
wp_transition_return_error (WP_TRANSITION (transition), g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"No global specified; cannot bind proxy"));
|
||||
}
|
||||
}
|
||||
wp_global_proxy_step_bind (object, transition, step, missing);
|
||||
break;
|
||||
case WP_TRANSITION_STEP_ERROR:
|
||||
break;
|
||||
|
|
@ -165,7 +226,9 @@ wp_global_proxy_bound (WpProxy * proxy, guint32 global_id)
|
|||
if (!priv->global) {
|
||||
wp_registry_prepare_new_global (wp_core_get_registry (core),
|
||||
global_id, PW_PERM_ALL, WP_GLOBAL_FLAG_OWNED_BY_PROXY,
|
||||
G_TYPE_FROM_INSTANCE (self), self, NULL, &priv->global);
|
||||
G_TYPE_FROM_INSTANCE (self), self,
|
||||
priv->properties ? wp_properties_peek_dict (priv->properties) : NULL,
|
||||
&priv->global);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,14 +269,19 @@ wp_global_proxy_class_init (WpGlobalProxyClass * klass)
|
|||
wp_global_get_type (),
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PERMISSIONS,
|
||||
g_param_spec_uint ("permissions", "permissions",
|
||||
"The pipewire global permissions", 0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_FACTORY_NAME,
|
||||
g_param_spec_string ("factory-name", "factory-name",
|
||||
"The factory name", "",
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_GLOBAL_PROPERTIES,
|
||||
g_param_spec_boxed ("global-properties", "global-properties",
|
||||
"The pipewire global properties", WP_TYPE_PROPERTIES,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PERMISSIONS,
|
||||
g_param_spec_uint ("permissions", "permissions",
|
||||
"The pipewire global permissions", 0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,19 +141,11 @@ wp_link_new_from_factory (WpCore * core,
|
|||
const gchar * factory_name, WpProperties * properties)
|
||||
{
|
||||
g_autoptr (WpProperties) props = properties;
|
||||
WpLink *self = NULL;
|
||||
struct pw_core *pw_core = wp_core_get_pw_core (core);
|
||||
|
||||
if (G_UNLIKELY (!pw_core)) {
|
||||
g_critical ("The WirePlumber core is not connected; link cannot be created");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_object_new (WP_TYPE_LINK, "core", core, NULL);
|
||||
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_create_object (pw_core,
|
||||
factory_name, PW_TYPE_INTERFACE_Link, PW_VERSION_LINK,
|
||||
props ? wp_properties_peek_dict (props) : NULL, 0));
|
||||
return self;
|
||||
return g_object_new (WP_TYPE_LINK,
|
||||
"core", core,
|
||||
"factory-name", factory_name,
|
||||
"global-properties", props,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -289,19 +289,11 @@ wp_node_new_from_factory (WpCore * core,
|
|||
const gchar * factory_name, WpProperties * properties)
|
||||
{
|
||||
g_autoptr (WpProperties) props = properties;
|
||||
WpNode *self = NULL;
|
||||
struct pw_core *pw_core = wp_core_get_pw_core (core);
|
||||
|
||||
if (G_UNLIKELY (!pw_core)) {
|
||||
g_critical ("The WirePlumber core is not connected; node cannot be created");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_object_new (WP_TYPE_NODE, "core", core, NULL);
|
||||
wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_create_object (pw_core,
|
||||
factory_name, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE,
|
||||
props ? wp_properties_peek_dict (props) : NULL, 0));
|
||||
return self;
|
||||
return g_object_new (WP_TYPE_NODE,
|
||||
"core", core,
|
||||
"factory-name", factory_name,
|
||||
"global-properties", props,
|
||||
NULL);
|
||||
}
|
||||
|
||||
WpNodeState
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue