-
Simon McVittie authored
This gives us direct access to Pipewire using its native protocol, similar to the direct access we already have to PulseAudio, X11 and Wayland. In a Flatpak subsandbox, applications will have to go via xdg-desktop-portal instead, as they do for any other Flatpak app. Signed-off-by:
Simon McVittie <smcv@collabora.com>
Simon McVittie authoredThis gives us direct access to Pipewire using its native protocol, similar to the direct access we already have to PulseAudio, X11 and Wayland. In a Flatpak subsandbox, applications will have to go via xdg-desktop-portal instead, as they do for any other Flatpak app. Signed-off-by:
Simon McVittie <smcv@collabora.com>
wrap-pipewire.c 4.38 KiB
/*
* 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);
}
}
}