diff --git a/pressure-vessel/meson.build b/pressure-vessel/meson.build index 3aff8c68c82c92030b7f69f8e4e3c7898d259053..a2bf3f37bf60f5d24ccd765c8927beb4048b9b9a 100644 --- a/pressure-vessel/meson.build +++ b/pressure-vessel/meson.build @@ -209,6 +209,8 @@ executable( 'wrap.c', 'wrap-flatpak.c', 'wrap-flatpak.h', + 'wrap-pipewire.c', + 'wrap-pipewire.h', 'wrap-setup.c', 'wrap-setup.h', ], diff --git a/pressure-vessel/wrap-pipewire.c b/pressure-vessel/wrap-pipewire.c new file mode 100644 index 0000000000000000000000000000000000000000..1bf77f22c2fde761f2d001b5c23d60685575ba21 --- /dev/null +++ b/pressure-vessel/wrap-pipewire.c @@ -0,0 +1,139 @@ +/* + * Copyright 2018-2021 Wim Taymans + * Copyright 2021 Collabora Ltd. + * + * SPDX-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "wrap-pipewire.h" + +/* From Pipewire 0.3.27 */ +#define PW_DEFAULT_REMOTE "pipewire-0" +#define DEFAULT_SYSTEM_RUNTIME_DIR "/run/pipewire" + +/* Adapted from Pipewire 0.3.27 */ +static const char * +get_remote (void) +{ + const char *name = NULL; + + name = getenv("PIPEWIRE_REMOTE"); + + if (name == NULL || name[0] == '\0') + name = PW_DEFAULT_REMOTE; + + return name; +} + +/* Adapted from Pipewire 0.3.27 */ +static const char * +get_runtime_dir (void) +{ + const char *runtime_dir; + + runtime_dir = g_getenv ("PIPEWIRE_RUNTIME_DIR"); + + if (runtime_dir == NULL) + runtime_dir = g_getenv ("XDG_RUNTIME_DIR"); + + if (runtime_dir == NULL) + runtime_dir = g_getenv ("HOME"); + + if (runtime_dir == NULL) + runtime_dir = g_getenv ("USERPROFILE"); + + if (runtime_dir == NULL) + runtime_dir = g_get_home_dir (); + + return runtime_dir; +} + +void +pv_wrap_add_pipewire_args (FlatpakBwrap *sharing_bwrap, + PvEnviron *container_env) +{ + g_autoptr(GDir) dir = NULL; + const char *remote = get_remote (); + const char *runtime_dir = get_runtime_dir (); + const char *member; + + /* Make Pipewire look in the container's XDG_RUNTIME_DIR */ + pv_environ_lock_env (container_env, "PIPEWIRE_RUNTIME_DIR", NULL); + + if (g_file_test (DEFAULT_SYSTEM_RUNTIME_DIR, G_FILE_TEST_IS_DIR)) + flatpak_bwrap_add_args (sharing_bwrap, + "--ro-bind", + DEFAULT_SYSTEM_RUNTIME_DIR, + DEFAULT_SYSTEM_RUNTIME_DIR, + NULL); + + dir = g_dir_open (runtime_dir, 0, NULL); + + if (dir == NULL) + return; + + for (member = g_dir_read_name (dir); + member != NULL; + member = g_dir_read_name (dir)) + { + /* Assume that anything starting with pipewire- is a (default or + * extra) Pipewire socket */ + if (g_str_has_prefix (member, "pipewire-")) + { + g_autofree gchar *host_socket = + g_build_filename (runtime_dir, member, NULL); + g_autofree gchar *container_socket = + g_strdup_printf ("/run/user/%d/%s", getuid (), member); + + flatpak_bwrap_add_args (sharing_bwrap, + "--ro-bind", + host_socket, + container_socket, + NULL); + } + } + + if (!g_str_has_prefix (remote, "pipewire-")) + { + /* If the configured Pipewire socket is something weird, remap it + * to be named pv-pipewire to avoid colliding with anything else */ + g_autofree gchar *host_socket = + g_build_filename (runtime_dir, remote, NULL); + + if (g_file_test (host_socket, G_FILE_TEST_EXISTS)) + { + g_autofree gchar *container_socket = + g_strdup_printf ("/run/user/%d/pv-pipewire", getuid ()); + + pv_environ_lock_env (container_env, "PIPEWIRE_REMOTE", "pv-pipewire"); + flatpak_bwrap_add_args (sharing_bwrap, + "--ro-bind", + host_socket, + container_socket, + NULL); + } + else + { + pv_environ_lock_env (container_env, "PIPEWIRE_REMOTE", NULL); + } + } +} diff --git a/pressure-vessel/wrap-pipewire.h b/pressure-vessel/wrap-pipewire.h new file mode 100644 index 0000000000000000000000000000000000000000..de32db90f999d684eded832a42c837abcef8f7f9 --- /dev/null +++ b/pressure-vessel/wrap-pipewire.h @@ -0,0 +1,32 @@ +/* + * Copyright 2021 Collabora Ltd. + * + * SPDX-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "environ.h" +#include "flatpak-bwrap-private.h" + +void pv_wrap_add_pipewire_args (FlatpakBwrap *sharing_bwrap, + PvEnviron *container_env); diff --git a/pressure-vessel/wrap-setup.c b/pressure-vessel/wrap-setup.c index ff4ac4d7476409ab0acab21d23a6082141792e0d..a8a19a4bda88590e1c1458c99c8baa6f90347ed4 100644 --- a/pressure-vessel/wrap-setup.c +++ b/pressure-vessel/wrap-setup.c @@ -86,6 +86,7 @@ pv_wrap_share_sockets (FlatpakBwrap *bwrap, flatpak_run_add_session_dbus_args (sharing_bwrap); flatpak_run_add_system_dbus_args (sharing_bwrap); flatpak_run_add_resolved_args (sharing_bwrap); + pv_wrap_add_pipewire_args (sharing_bwrap, container_env); } envp = pv_bwrap_steal_envp (sharing_bwrap); diff --git a/pressure-vessel/wrap-setup.h b/pressure-vessel/wrap-setup.h index 9dc1f5f7fb43948bd0ede19a33e4714ff7679886..aae933076e390fc80124c26236b6d0300d5003ea 100644 --- a/pressure-vessel/wrap-setup.h +++ b/pressure-vessel/wrap-setup.h @@ -26,6 +26,7 @@ #include "flatpak-bwrap-private.h" #include "flatpak-exports-private.h" +#include "wrap-pipewire.h" void pv_wrap_share_sockets (FlatpakBwrap *bwrap, PvEnviron *container_env,