mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-10 13:30:05 -05:00
pulse-server: add condition support in pulse.cmd
So that a config override can disable the execution of the command by setting the property to false in the pulse.properties config override. Expose some conf.c method for this purpose.
This commit is contained in:
parent
12c8cdf69b
commit
9243ed0cbd
5 changed files with 44 additions and 19 deletions
|
|
@ -60,11 +60,17 @@ context.exec = [
|
|||
# load-module : loads a module with args and flags
|
||||
# args = "<module-name> <module-args>"
|
||||
# ( flags = [ nofail ] )
|
||||
# ( condition = [ { <key1> = <value1>, ... } ... ] )
|
||||
# conditions will check the pulse.properties key/values.
|
||||
pulse.cmd = [
|
||||
{ cmd = "load-module" args = "module-always-sink" flags = [ ] }
|
||||
{ cmd = "load-module" args = "module-device-manager" flags = [ ] }
|
||||
{ cmd = "load-module" args = "module-device-restore" flags = [ ] }
|
||||
{ cmd = "load-module" args = "module-stream-restore" flags = [ ] }
|
||||
{ cmd = "load-module" args = "module-always-sink" flags = [ ]
|
||||
condition = [ { pulse.cmd.always-sink = !false } ] }
|
||||
{ cmd = "load-module" args = "module-device-manager" flags = [ ]
|
||||
condition = [ { pulse.cmd.device-manager = !false } ] }
|
||||
{ cmd = "load-module" args = "module-device-restore" flags = [ ]
|
||||
condition = [ { pulse.cmd.device-restore = !false } ] }
|
||||
{ cmd = "load-module" args = "module-stream-restore" flags = [ ]
|
||||
condition = [ { pulse.cmd.stream-restore = !false } ] }
|
||||
#{ cmd = "load-module" args = "module-switch-on-connect" }
|
||||
#{ cmd = "load-module" args = "module-gsettings" flags = [ nofail ] }
|
||||
]
|
||||
|
|
|
|||
|
|
@ -256,10 +256,12 @@
|
|||
* # Extra commands can be executed here.
|
||||
* # load-module : loads a module with args and flags
|
||||
* # args = "<module-name> <module-args>"
|
||||
* # flags = [ "no-fail" ]
|
||||
* # ( flags = [ "no-fail" ] )
|
||||
* # ( condition = [ { <key1> = <value1>, ... } ... ] )
|
||||
* # conditions will check the pulse.properties key/values.
|
||||
* pulse.cmd = [
|
||||
* { cmd = "load-module" args = "module-always-sink" flags = [ ] }
|
||||
* #{ cmd = "load-module" args = "module-switch-on-connect" }
|
||||
* #{ cmd = "load-module" args = "module-switch-on-connect" condition = [ { pulse.cmd.switch-on-connect = true } ]
|
||||
* #{ cmd = "load-module" args = "module-gsettings" flags = [ "nofail" ] }
|
||||
* ]
|
||||
*\endcode
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ static int parse_cmd(void *user_data, const char *location,
|
|||
const char *section, const char *str, size_t len)
|
||||
{
|
||||
struct impl *impl = user_data;
|
||||
struct spa_json it[2];
|
||||
struct spa_json it[3];
|
||||
char key[512];
|
||||
int res = 0;
|
||||
|
||||
|
|
@ -81,24 +81,36 @@ static int parse_cmd(void *user_data, const char *location,
|
|||
while (spa_json_enter_object(&it[0], &it[1]) > 0) {
|
||||
char *cmd = NULL, *args = NULL, *flags = NULL;
|
||||
const char *val;
|
||||
int len;
|
||||
bool have_match = true;
|
||||
int l;
|
||||
|
||||
while ((len = spa_json_object_next(&it[1], key, sizeof(key), &val)) > 0) {
|
||||
while ((l = spa_json_object_next(&it[1], key, sizeof(key), &val)) > 0) {
|
||||
if (spa_streq(key, "cmd")) {
|
||||
cmd = (char*)val;
|
||||
spa_json_parse_stringn(val, len, cmd, len+1);
|
||||
spa_json_parse_stringn(val, l, cmd, l+1);
|
||||
} else if (spa_streq(key, "args")) {
|
||||
args = (char*)val;
|
||||
spa_json_parse_stringn(val, len, args, len+1);
|
||||
spa_json_parse_stringn(val, l, args, l+1);
|
||||
} else if (spa_streq(key, "flags")) {
|
||||
if (spa_json_is_container(val, len))
|
||||
len = spa_json_container_len(&it[1], val, len);
|
||||
if (spa_json_is_container(val, l))
|
||||
l = spa_json_container_len(&it[1], val, l);
|
||||
flags = (char*)val;
|
||||
spa_json_parse_stringn(val, len, flags, len+1);
|
||||
spa_json_parse_stringn(val, l, flags, l+1);
|
||||
} else if (spa_streq(key, "condition")) {
|
||||
if (!spa_json_is_array(val, l)) {
|
||||
pw_log_warn("expected array for condition in '%.*s'",
|
||||
(int)l, str);
|
||||
break;
|
||||
}
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
have_match = pw_conf_find_match(&it[2], &impl->props->dict, true);
|
||||
} else {
|
||||
pw_log_warn("unknown pulse.cmd key %s", key);
|
||||
}
|
||||
}
|
||||
if (!have_match)
|
||||
continue;
|
||||
|
||||
if (cmd != NULL)
|
||||
res = do_cmd(impl, cmd, args, flags);
|
||||
if (res < 0)
|
||||
|
|
|
|||
|
|
@ -628,7 +628,8 @@ static int load_module(struct pw_context *context, const char *key, const char *
|
|||
* "!null" -> same as !null
|
||||
* !"null" and "!\"null\"" matches anything that is not the string "null"
|
||||
*/
|
||||
static bool find_match(struct spa_json *arr, const struct spa_dict *props, bool condition)
|
||||
SPA_EXPORT
|
||||
bool pw_conf_find_match(struct spa_json *arr, const struct spa_dict *props, bool condition)
|
||||
{
|
||||
struct spa_json it[1];
|
||||
const char *as = arr->cur;
|
||||
|
|
@ -784,7 +785,7 @@ static int parse_modules(void *user_data, const char *location,
|
|||
break;
|
||||
}
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
have_match = find_match(&it[2], &context->properties->dict, true);
|
||||
have_match = pw_conf_find_match(&it[2], &context->properties->dict, true);
|
||||
} else {
|
||||
pw_log_warn("unknown module key '%s' in '%.*s'", key,
|
||||
(int)len, str);
|
||||
|
|
@ -886,7 +887,7 @@ static int parse_objects(void *user_data, const char *location,
|
|||
break;
|
||||
}
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
have_match = find_match(&it[2], &context->properties->dict, true);
|
||||
have_match = pw_conf_find_match(&it[2], &context->properties->dict, true);
|
||||
} else {
|
||||
pw_log_warn("unknown object key '%s' in '%.*s'", key,
|
||||
(int)len, str);
|
||||
|
|
@ -1056,7 +1057,7 @@ static int parse_exec(void *user_data, const char *location,
|
|||
goto next;
|
||||
}
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
have_match = find_match(&it[2], &context->properties->dict, true);
|
||||
have_match = pw_conf_find_match(&it[2], &context->properties->dict, true);
|
||||
} else {
|
||||
pw_log_warn("unknown exec key '%s' in '%.*s'", key,
|
||||
(int)len, str);
|
||||
|
|
@ -1296,7 +1297,7 @@ int pw_conf_match_rules(const char *str, size_t len, const char *location,
|
|||
}
|
||||
|
||||
spa_json_enter(&it[1], &it[2]);
|
||||
have_match = find_match(&it[2], props, false);
|
||||
have_match = pw_conf_find_match(&it[2], props, false);
|
||||
}
|
||||
else if (spa_streq(key, "actions")) {
|
||||
if (!spa_json_is_object(val, l)) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef PIPEWIRE_CONF_H
|
||||
#define PIPEWIRE_CONF_H
|
||||
|
||||
#include <spa/utils/json-core.h>
|
||||
|
||||
#include <pipewire/context.h>
|
||||
|
||||
/** \defgroup pw_conf Configuration
|
||||
|
|
@ -21,6 +23,8 @@ int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties
|
|||
int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf);
|
||||
int pw_conf_save_state(const char *prefix, const char *name, const struct pw_properties *conf);
|
||||
|
||||
bool pw_conf_find_match(struct spa_json *arr, const struct spa_dict *props, bool condition);
|
||||
|
||||
int pw_conf_section_update_props(const struct spa_dict *conf,
|
||||
const char *section, struct pw_properties *props);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue