mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	properties: ignore some property updates
Ignore property updates for keys that we manage ourselves like the object.id, node.id etc. Otherwise a client can replace this with their local ids and cause confusion.
This commit is contained in:
		
							parent
							
								
									dd1bf796cb
								
							
						
					
					
						commit
						08ea7d5cd6
					
				
					 6 changed files with 88 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -133,21 +133,39 @@ static int client_error(void *object, uint32_t id, int res, const char *error)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool has_key(const char *keys[], const char *key)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 0; keys[i]; i++) {
 | 
			
		||||
		if (strcmp(keys[i], key) == 0)
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_resource *resource;
 | 
			
		||||
	int changed = 0;
 | 
			
		||||
	uint32_t i;
 | 
			
		||||
	const char *old;
 | 
			
		||||
	const char *old, *ignored[] = {
 | 
			
		||||
		PW_KEY_OBJECT_ID,
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < dict->n_items; i++) {
 | 
			
		||||
		if (filter && strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
 | 
			
		||||
		    (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL &&
 | 
			
		||||
		    (dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) {
 | 
			
		||||
			pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'",
 | 
			
		||||
					client, dict->items[i].key, old,
 | 
			
		||||
					dict->items[i].value);
 | 
			
		||||
			continue;
 | 
			
		||||
		if (filter) {
 | 
			
		||||
			if (strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
 | 
			
		||||
			    (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL &&
 | 
			
		||||
			    (dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) {
 | 
			
		||||
				pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'",
 | 
			
		||||
						client, dict->items[i].key, old,
 | 
			
		||||
						dict->items[i].value);
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			if (has_key(ignored, dict->items[i].key))
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
                changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -643,11 +643,18 @@ static void emit_info_changed(struct pw_impl_device *device)
 | 
			
		|||
	device->info.change_mask = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int update_properties(struct pw_impl_device *device, const struct spa_dict *dict)
 | 
			
		||||
static int update_properties(struct pw_impl_device *device, const struct spa_dict *dict, bool filter)
 | 
			
		||||
{
 | 
			
		||||
	int changed;
 | 
			
		||||
	const char *ignored[] = {
 | 
			
		||||
		PW_KEY_OBJECT_ID,
 | 
			
		||||
		PW_KEY_MODULE_ID,
 | 
			
		||||
		PW_KEY_FACTORY_ID,
 | 
			
		||||
		PW_KEY_CLIENT_ID,
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	changed = pw_properties_update(device->properties, dict);
 | 
			
		||||
	changed = pw_properties_update_ignore(device->properties, dict, filter ? ignored : NULL);
 | 
			
		||||
	device->info.props = &device->properties->dict;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug(NAME" %p: updated %d properties", device, changed);
 | 
			
		||||
| 
						 | 
				
			
			@ -726,7 +733,7 @@ static void device_info(void *data, const struct spa_device_info *info)
 | 
			
		|||
			device, info->flags, info->change_mask);
 | 
			
		||||
 | 
			
		||||
	if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PROPS) {
 | 
			
		||||
		update_properties(device, info->props);
 | 
			
		||||
		update_properties(device, info->props, true);
 | 
			
		||||
	}
 | 
			
		||||
	if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) {
 | 
			
		||||
		uint32_t i;
 | 
			
		||||
| 
						 | 
				
			
			@ -894,7 +901,7 @@ const struct pw_properties *pw_impl_device_get_properties(struct pw_impl_device
 | 
			
		|||
SPA_EXPORT
 | 
			
		||||
int pw_impl_device_update_properties(struct pw_impl_device *device, const struct spa_dict *dict)
 | 
			
		||||
{
 | 
			
		||||
	int changed = update_properties(device, dict);
 | 
			
		||||
	int changed = update_properties(device, dict, false);
 | 
			
		||||
	emit_info_changed(device);
 | 
			
		||||
	return changed;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1220,11 +1220,19 @@ const struct pw_properties *pw_impl_node_get_properties(struct pw_impl_node *nod
 | 
			
		|||
	return node->properties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict)
 | 
			
		||||
static int update_properties(struct pw_impl_node *node, const struct spa_dict *dict, bool filter)
 | 
			
		||||
{
 | 
			
		||||
	int changed;
 | 
			
		||||
	const char *ignored[] = {
 | 
			
		||||
		PW_KEY_OBJECT_ID,
 | 
			
		||||
		PW_KEY_MODULE_ID,
 | 
			
		||||
		PW_KEY_FACTORY_ID,
 | 
			
		||||
		PW_KEY_CLIENT_ID,
 | 
			
		||||
		PW_KEY_DEVICE_ID,
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	changed = pw_properties_update(node->properties, dict);
 | 
			
		||||
	changed = pw_properties_update_ignore(node->properties, dict, filter ? ignored : NULL);
 | 
			
		||||
	node->info.props = &node->properties->dict;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug(NAME" %p: updated %d properties", node, changed);
 | 
			
		||||
| 
						 | 
				
			
			@ -1239,7 +1247,7 @@ static int update_properties(struct pw_impl_node *node, const struct spa_dict *d
 | 
			
		|||
SPA_EXPORT
 | 
			
		||||
int pw_impl_node_update_properties(struct pw_impl_node *node, const struct spa_dict *dict)
 | 
			
		||||
{
 | 
			
		||||
	int changed = update_properties(node, dict);
 | 
			
		||||
	int changed = update_properties(node, dict, false);
 | 
			
		||||
	emit_info_changed(node, false);
 | 
			
		||||
	return changed;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1265,7 +1273,7 @@ static void node_info(void *data, const struct spa_node_info *info)
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (info->change_mask & SPA_NODE_CHANGE_MASK_PROPS) {
 | 
			
		||||
		update_properties(node, info->props);
 | 
			
		||||
		update_properties(node, info->props, true);
 | 
			
		||||
	}
 | 
			
		||||
	if (info->change_mask & SPA_NODE_CHANGE_MASK_PARAMS) {
 | 
			
		||||
		uint32_t i;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -266,11 +266,19 @@ int pw_impl_port_release_mix(struct pw_impl_port *port, struct pw_impl_port_mix
 | 
			
		|||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int update_properties(struct pw_impl_port *port, const struct spa_dict *dict)
 | 
			
		||||
static int update_properties(struct pw_impl_port *port, const struct spa_dict *dict, bool filter)
 | 
			
		||||
{
 | 
			
		||||
	int changed;
 | 
			
		||||
	const char *ignored[] = {
 | 
			
		||||
		PW_KEY_OBJECT_ID,
 | 
			
		||||
		PW_KEY_PORT_DIRECTION,
 | 
			
		||||
		PW_KEY_PORT_CONTROL,
 | 
			
		||||
		PW_KEY_NODE_ID,
 | 
			
		||||
		PW_KEY_PORT_ID,
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	changed = pw_properties_update(port->properties, dict);
 | 
			
		||||
	changed = pw_properties_update_ignore(port->properties, dict, filter ? ignored : NULL);
 | 
			
		||||
	port->info.props = &port->properties->dict;
 | 
			
		||||
 | 
			
		||||
	if (changed) {
 | 
			
		||||
| 
						 | 
				
			
			@ -354,7 +362,7 @@ static void update_info(struct pw_impl_port *port, const struct spa_port_info *i
 | 
			
		|||
	}
 | 
			
		||||
	if (info->change_mask & SPA_PORT_CHANGE_MASK_PROPS) {
 | 
			
		||||
		if (info->props) {
 | 
			
		||||
			update_properties(port, info->props);
 | 
			
		||||
			update_properties(port, info->props, true);
 | 
			
		||||
		} else {
 | 
			
		||||
			pw_log_warn(NAME" %p: port PROPS update but no properties", port);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -617,10 +625,8 @@ const struct pw_properties *pw_impl_port_get_properties(struct pw_impl_port *por
 | 
			
		|||
SPA_EXPORT
 | 
			
		||||
int pw_impl_port_update_properties(struct pw_impl_port *port, const struct spa_dict *dict)
 | 
			
		||||
{
 | 
			
		||||
	int changed = update_properties(port, dict);
 | 
			
		||||
 | 
			
		||||
	int changed = update_properties(port, dict, false);
 | 
			
		||||
	emit_info_changed(port);
 | 
			
		||||
 | 
			
		||||
	return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -248,6 +248,30 @@ int pw_properties_update_keys(struct pw_properties *props,
 | 
			
		|||
	return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool has_key(const char *keys[], const char *key)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 0; keys[i]; i++) {
 | 
			
		||||
		if (strcmp(keys[i], key) == 0)
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPA_EXPORT
 | 
			
		||||
int pw_properties_update_ignore(struct pw_properties *props,
 | 
			
		||||
		const struct spa_dict *dict, const char *ignore[])
 | 
			
		||||
{
 | 
			
		||||
	const struct spa_dict_item *it;
 | 
			
		||||
	int changed = 0;
 | 
			
		||||
 | 
			
		||||
	spa_dict_for_each(it, dict) {
 | 
			
		||||
		if (ignore == NULL || !has_key(ignore, it->key))
 | 
			
		||||
			changed += pw_properties_set(props, it->key, it->value);
 | 
			
		||||
	}
 | 
			
		||||
	return changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Clear a properties object
 | 
			
		||||
 *
 | 
			
		||||
 * \param properties properties to clear
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,8 @@ pw_properties_copy(const struct pw_properties *properties);
 | 
			
		|||
 | 
			
		||||
int pw_properties_update_keys(struct pw_properties *props,
 | 
			
		||||
		     const struct spa_dict *dict, const char *keys[]);
 | 
			
		||||
int pw_properties_update_ignore(struct pw_properties *props,
 | 
			
		||||
		const struct spa_dict *dict, const char *ignore[]);
 | 
			
		||||
 | 
			
		||||
int pw_properties_update(struct pw_properties *oldprops,
 | 
			
		||||
		     const struct spa_dict *dict);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue