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;
 | 
						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)
 | 
					static int update_properties(struct pw_impl_client *client, const struct spa_dict *dict, bool filter)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_resource *resource;
 | 
						struct pw_resource *resource;
 | 
				
			||||||
	int changed = 0;
 | 
						int changed = 0;
 | 
				
			||||||
	uint32_t i;
 | 
						uint32_t i;
 | 
				
			||||||
	const char *old;
 | 
						const char *old, *ignored[] = {
 | 
				
			||||||
 | 
							PW_KEY_OBJECT_ID,
 | 
				
			||||||
 | 
							NULL
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < dict->n_items; i++) {
 | 
					        for (i = 0; i < dict->n_items; i++) {
 | 
				
			||||||
		if (filter && strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
 | 
							if (filter) {
 | 
				
			||||||
 | 
								if (strstr(dict->items[i].key, "pipewire.") == dict->items[i].key &&
 | 
				
			||||||
			    (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL &&
 | 
								    (old = pw_properties_get(client->properties, dict->items[i].key)) != NULL &&
 | 
				
			||||||
			    (dict->items[i].value == NULL || strcmp(old, dict->items[i].value) != 0)) {
 | 
								    (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'",
 | 
									pw_log_warn(NAME" %p: refuse property update '%s' from '%s' to '%s'",
 | 
				
			||||||
						client, dict->items[i].key, old,
 | 
											client, dict->items[i].key, old,
 | 
				
			||||||
						dict->items[i].value);
 | 
											dict->items[i].value);
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (has_key(ignored, dict->items[i].key))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
                changed += pw_properties_set(client->properties, dict->items[i].key, dict->items[i].value);
 | 
					                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;
 | 
						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;
 | 
						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;
 | 
						device->info.props = &device->properties->dict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug(NAME" %p: updated %d properties", device, changed);
 | 
						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);
 | 
								device, info->flags, info->change_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PROPS) {
 | 
						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) {
 | 
						if (info->change_mask & SPA_DEVICE_CHANGE_MASK_PARAMS) {
 | 
				
			||||||
		uint32_t i;
 | 
							uint32_t i;
 | 
				
			||||||
| 
						 | 
					@ -894,7 +901,7 @@ const struct pw_properties *pw_impl_device_get_properties(struct pw_impl_device
 | 
				
			||||||
SPA_EXPORT
 | 
					SPA_EXPORT
 | 
				
			||||||
int pw_impl_device_update_properties(struct pw_impl_device *device, const struct spa_dict *dict)
 | 
					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);
 | 
						emit_info_changed(device);
 | 
				
			||||||
	return changed;
 | 
						return changed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1220,11 +1220,19 @@ const struct pw_properties *pw_impl_node_get_properties(struct pw_impl_node *nod
 | 
				
			||||||
	return node->properties;
 | 
						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;
 | 
						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;
 | 
						node->info.props = &node->properties->dict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug(NAME" %p: updated %d properties", node, changed);
 | 
						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
 | 
					SPA_EXPORT
 | 
				
			||||||
int pw_impl_node_update_properties(struct pw_impl_node *node, const struct spa_dict *dict)
 | 
					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);
 | 
						emit_info_changed(node, false);
 | 
				
			||||||
	return changed;
 | 
						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) {
 | 
						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) {
 | 
						if (info->change_mask & SPA_NODE_CHANGE_MASK_PARAMS) {
 | 
				
			||||||
		uint32_t i;
 | 
							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;
 | 
						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;
 | 
						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;
 | 
						port->info.props = &port->properties->dict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (changed) {
 | 
						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->change_mask & SPA_PORT_CHANGE_MASK_PROPS) {
 | 
				
			||||||
		if (info->props) {
 | 
							if (info->props) {
 | 
				
			||||||
			update_properties(port, info->props);
 | 
								update_properties(port, info->props, true);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			pw_log_warn(NAME" %p: port PROPS update but no properties", port);
 | 
								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
 | 
					SPA_EXPORT
 | 
				
			||||||
int pw_impl_port_update_properties(struct pw_impl_port *port, const struct spa_dict *dict)
 | 
					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);
 | 
						emit_info_changed(port);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return changed;
 | 
						return changed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,6 +248,30 @@ int pw_properties_update_keys(struct pw_properties *props,
 | 
				
			||||||
	return changed;
 | 
						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
 | 
					/** Clear a properties object
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param properties properties to clear
 | 
					 * \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,
 | 
					int pw_properties_update_keys(struct pw_properties *props,
 | 
				
			||||||
		     const struct spa_dict *dict, const char *keys[]);
 | 
							     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,
 | 
					int pw_properties_update(struct pw_properties *oldprops,
 | 
				
			||||||
		     const struct spa_dict *dict);
 | 
							     const struct spa_dict *dict);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue