0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 04:42:18 +02:00

linux-v4l2: Use flatpak-spawn when inside a Flatpak sandbox

It is not possible to run host system executables like modinfo, pkexec,
and modprobe inside a Flatpak sandbox. However, Flatpak provides a way
to run command on the host system: the flatpak-spawn executable.

flatpak-spawn is a tiny helper that, when executed with the '--host'
parameter, talks to the org.freedesktop.Flatpak D-Bus interface to run
and retrieve the return value of the executable. This provides OBS Studio
a way to escape this sandbox limitation without opening large holes in
the sandbox.

Make v4l2's implementation of VirtualCam run system commands using
flatpak-spawn when inside a Flatpak sandbox. The detection of the sandbox
is done by checking the existence of the /.flatpak-info file, which is
created by Flatpak itself, and only exists inside the sandbox. If OBS
Studio is not running inside a Flatpak sandbox, run the exact same command
it used to run before this commit.

Add the permission to talk to the org.freedesktop.Flatpak D-Bus interface
to the Flatpak manifest, so we can run flatpak-spawn with the '--host'
parameter.

Notice that the same constraints apply with and without Flatpak: the host
system needs to have the v4l2loopback kernel module available for the v4l2
implementation of VirtualCam to work.
This commit is contained in:
Georges Basile Stavracas Neto 2021-04-18 12:51:20 -03:00 committed by Jim
parent 44ee91188f
commit 7a87777225
2 changed files with 34 additions and 4 deletions

View File

@ -14,6 +14,7 @@
"--filesystem=xdg-run/pipewire-0",
"--filesystem=host",
"--talk-name=org.kde.StatusNotifierWatcher",
"--talk-name=org.freedesktop.Flatpak",
"--talk-name=org.freedesktop.ScreenSaver",
"--talk-name=org.freedesktop.PowerManagement.Inhibit",
"--talk-name=org.freedesktop.Notifications",

View File

@ -1,4 +1,5 @@
#include <obs-module.h>
#include <util/dstr.h>
#include <util/platform.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
@ -26,6 +27,35 @@ static void virtualcam_destroy(void *data)
bfree(data);
}
static bool is_flatpak_sandbox(void)
{
static bool flatpak_info_exists = false;
static bool initialized = false;
if (!initialized) {
flatpak_info_exists = access("/.flatpak-info", F_OK) == 0;
initialized = true;
}
return flatpak_info_exists;
}
static int run_command(const char *command)
{
struct dstr str;
int result;
dstr_init_copy(&str, "PATH=\"$PATH:/sbin\" ");
if (is_flatpak_sandbox())
dstr_cat(&str, "flatpak-spawn --host ");
dstr_cat(&str, command);
result = system(str.array);
dstr_free(&str);
return result;
}
static bool loopback_module_loaded()
{
bool loaded = false;
@ -56,8 +86,7 @@ bool loopback_module_available()
return true;
}
if (system("PATH=\"$PATH:/sbin\" modinfo v4l2loopback >/dev/null 2>&1") ==
0) {
if (run_command("modinfo v4l2loopback >/dev/null 2>&1") == 0) {
return true;
}
@ -66,8 +95,8 @@ bool loopback_module_available()
static int loopback_module_load()
{
return system(
"PATH=\"$PATH:/sbin\" pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5");
return run_command(
"pkexec modprobe v4l2loopback exclusive_caps=1 card_label='OBS Virtual Camera' && sleep 0.5");
}
static void *virtualcam_create(obs_data_t *settings, obs_output_t *output)