diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0fce1cf1..87b3852f5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -96,6 +96,7 @@ include: debhelper-compat findutils git + libapparmor-dev libasound2-dev libavcodec-dev libavfilter-dev @@ -107,6 +108,7 @@ include: libgstreamer-plugins-base1.0-dev libsbc-dev libsdl2-dev + libsnapd-glib-dev libudev-dev libva-dev libv4l-dev @@ -247,7 +249,7 @@ build_on_ubuntu: - .build stage: build variables: - MESON_OPTIONS: "-Dsession-managers=[]" + MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=enabled" .build_on_fedora: extends: @@ -274,6 +276,7 @@ build_on_fedora: -Dsdl2=enabled -Dsndfile=enabled -Dsession-managers=[] + -Dsnap=disabled artifacts: name: pipewire-$CI_COMMIT_SHA when: always @@ -289,7 +292,7 @@ build_on_alpine: - .build stage: build variables: - MESON_OPTIONS: "-Dsession-managers=[]" + MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled" # build with all auto() options enabled build_all: @@ -308,6 +311,7 @@ build_all: -Dsession-managers=[] -Dc_args=['-UFASTPATH'] -Dcpp_args=['-UFASTPATH'] + -Dsnap=disabled parallel: matrix: - CC: [gcc, clang] @@ -317,7 +321,7 @@ build_with_no_commandline_options: extends: - .build_on_fedora variables: - MESON_OPTIONS: "-Dsession-managers=[]" + MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled" parallel: matrix: - CC: [gcc, clang] @@ -353,7 +357,7 @@ build_release: extends: - .build_on_fedora variables: - MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true -Dsession-managers=[]" + MESON_OPTIONS: "-Dtest=enabled -Dbuildtype=release -Db_ndebug=true -Dsession-managers=[] -Dsnap=disabled" parallel: matrix: - CC: [gcc, clang] @@ -367,7 +371,7 @@ build_session_managers: - meson compile -C "$BUILD_DIR" $COMPILE_ARGS - meson install -C "$BUILD_DIR" --no-rebuild variables: - MESON_OPTIONS: "-Dsession-managers=$SESSION_MANAGERS" + MESON_OPTIONS: "-Dsession-managers=$SESSION_MANAGERS -Dsnap=disabled" parallel: matrix: - SESSION_MANAGERS: ["[]", "wireplumber", "media-session", "media-session,wireplumber", "wireplumber,media-session" ] @@ -384,7 +388,7 @@ build_meson_prerelease: - meson compile -C "$BUILD_DIR" $COMPILE_ARGS - meson install -C "$BUILD_DIR" --no-rebuild variables: - MESON_OPTIONS: "-Dsession-managers=wireplumber,media-session" + MESON_OPTIONS: "-Dsession-managers=wireplumber,media-session -Dsnap=disabled" allow_failure: true build_meson_exact_release: @@ -402,7 +406,7 @@ build_meson_exact_release: - meson compile -C "$BUILD_DIR" $COMPILE_ARGS - meson install -C "$BUILD_DIR" --no-rebuild variables: - MESON_OPTIONS: "-Dsession-managers=[]" + MESON_OPTIONS: "-Dsession-managers=[] -Dsnap=disabled" valgrind: extends: diff --git a/meson.build b/meson.build index 90a599161..906305c96 100644 --- a/meson.build +++ b/meson.build @@ -433,6 +433,22 @@ summary({'lilv (for lv2 plugins)': lilv_lib.found()}, bool_yn: true) libffado_dep = dependency('libffado', required: get_option('libffado')) summary({'ffado': libffado_dep.found()}, bool_yn: true) +glib2_snap_dep = dependency('glib-2.0', required : get_option('snap')) +gio2_snap_dep = dependency('gio-2.0', required : get_option('snap')) +apparmor_snap_dep = dependency('libapparmor', required : get_option('snap')) +if dependency('snapd-glib-2', required: false).found() + snap_dep = dependency('snapd-glib-2', required : get_option('snap')) +else + snap_dep = dependency('snapd-glib', required : get_option('snap')) +endif +if snap_dep.found() and glib2_snap_dep.found() and gio2_snap_dep.found() and apparmor_snap_dep.found() + cdata.set('HAVE_SNAP', 1) + snap_deps = [glib2_snap_dep, gio2_snap_dep, snap_dep, apparmor_snap_dep] +endif +summary({'GLib-2.0 (Snap support)': glib2_snap_dep.found()}, bool_yn: true, section: 'Misc dependencies') +summary({'Gio-2.0 (Snap support)': gio2_snap_dep.found()}, bool_yn: true, section: 'Misc dependencies') +summary({'Apparmor (Snap support)': apparmor_snap_dep.found()}, bool_yn: true, section: 'Misc dependencies') +summary({'Snapd-glib (Snap support)': snap_dep.found()}, bool_yn: true, section: 'Misc dependencies') check_functions = [ ['gettid', '#include ', ['-D_GNU_SOURCE'], []], diff --git a/meson_options.txt b/meson_options.txt index 15664aaeb..59001f0ea 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -334,3 +334,7 @@ option('gsettings-pulse-schema', description: 'Install gsettings schema for pulseaudio', type: 'feature', value: 'auto') +option('snap', + description : 'Snap support is available.', + type : 'feature', + value : 'auto') diff --git a/src/modules/meson.build b/src/modules/meson.build index 85f309a8c..37cb854a9 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -393,6 +393,13 @@ pipewire_module_protocol_pulse_sources = [ 'module-protocol-pulse/modules/module-zeroconf-discover.c', ] +if snap_dep.found() and glib2_snap_dep.found() and gio2_snap_dep.found() and apparmor_snap_dep.found() + pipewire_module_protocol_pulse_sources += [ + 'module-protocol-pulse/snap-policy.c', + ] + pipewire_module_protocol_pulse_deps += snap_deps +endif + if dbus_dep.found() pipewire_module_protocol_pulse_sources += [ 'module-protocol-pulse/dbus-name.c', diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index adcd60bbb..9145824e1 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -42,6 +42,9 @@ #include "stream.h" #include "utils.h" #include "flatpak-utils.h" +#ifdef HAVE_SNAP +#include "snap-policy.h" +#endif #define LISTEN_BACKLOG 32 #define MAX_CLIENTS 64 @@ -408,6 +411,9 @@ on_connect(void *data, int fd, uint32_t mask) if (server->addr.ss_family == AF_UNIX) { spa_autofree char *app_id = NULL, *devices = NULL; +#ifdef HAVE_SNAP + pw_sandbox_access_t snap_access; +#endif #ifdef SO_PRIORITY val = 6; @@ -446,6 +452,21 @@ on_connect(void *data, int fd, uint32_t mask) else pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, NULL); } + // check SNAP permissions +#ifdef HAVE_SNAP + snap_access = pw_snap_get_audio_permissions(client, client_fd, &app_id); + if ((snap_access & PW_SANDBOX_ACCESS_NOT_A_SANDBOX) == 0) { + pw_properties_set(client->props, PW_KEY_SNAP_ID, app_id); + + pw_properties_set(client->props, + PW_KEY_SNAP_PLAYBACK_ALLOWED, + (snap_access & PW_SANDBOX_ACCESS_PLAYBACK) ? "true" : "false"); + + pw_properties_set(client->props, + PW_KEY_SNAP_RECORD_ALLOWED, + (snap_access & PW_SANDBOX_ACCESS_RECORD) ? "true" : "false"); + } +#endif } else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {