From 9ce37b783e9f26562f42f8032120c4b064b713d2 Mon Sep 17 00:00:00 2001 From: Clayton Craft Date: Mon, 24 Jun 2024 15:24:48 -0700 Subject: [PATCH] systemd: fork pipewire to build w/ systemd support (MR 5142) (MR 5563) Unfortunately there are some code paths that are required to support socket activation, and they are only enabled at build time with -Dsystemd=enabled. On the bright side, service/socket unit files are included... Also note that I disabled test on armv7 since they fail in our CI using qemu on x86_64. They pass in Alpine on native armv7. --- ...ash-when-receiving-signal-from-modem.patch | 51 ++++ extra-repos/systemd/pipewire/APKBUILD | 261 ++++++++++++++++++ .../systemd/pipewire/pipewire-launcher.sh | 22 ++ extra-repos/systemd/pipewire/pipewire.desktop | 10 + .../systemd/pipewire/pipewire.post-install | 5 + .../systemd/pipewire/pipewire.post-upgrade | 14 + 6 files changed, 363 insertions(+) create mode 100644 extra-repos/systemd/pipewire/0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch create mode 100644 extra-repos/systemd/pipewire/APKBUILD create mode 100644 extra-repos/systemd/pipewire/pipewire-launcher.sh create mode 100644 extra-repos/systemd/pipewire/pipewire.desktop create mode 100644 extra-repos/systemd/pipewire/pipewire.post-install create mode 100644 extra-repos/systemd/pipewire/pipewire.post-upgrade diff --git a/extra-repos/systemd/pipewire/0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch b/extra-repos/systemd/pipewire/0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch new file mode 100644 index 000000000..cf82ad0b8 --- /dev/null +++ b/extra-repos/systemd/pipewire/0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch @@ -0,0 +1,51 @@ +From 2501b347efac03bfb2fb5007784933fcf61e135e Mon Sep 17 00:00:00 2001 +From: Arnav Singh +Date: Sat, 15 Jun 2024 10:11:38 -0700 +Subject: [PATCH] spa: bluez: fix crash when receiving signal from modemmanager + +6e581deb9159fe12a14b3072a79b02bba87afa62 added an `spa_autoptr(DbusMessage) m` +for the new message sent out when a signal is received from modemmanager. +However this ended up shadowing the original `m` function arg, +so the code that wanted to interrogate the original arg with +`dbus_get_message_path` etc ended up interrogating this `NULL` value instead. +This triggered a NULL-check in `dbus_get_message_path` and caused +the process to abort. + +Original downstream report: https://gitlab.com/postmarketOS/pmaports/-/issues/2886 +--- + spa/plugins/bluez5/modemmanager.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/spa/plugins/bluez5/modemmanager.c b/spa/plugins/bluez5/modemmanager.c +index f30876f5c..0ed3d46fe 100644 +--- a/spa/plugins/bluez5/modemmanager.c ++++ b/spa/plugins/bluez5/modemmanager.c +@@ -570,7 +570,7 @@ static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void + const char *path; + struct call *call_object; + const char *mm_call_interface = MM_DBUS_INTERFACE_CALL; +- spa_autoptr(DBusMessage) m = NULL; ++ spa_autoptr(DBusMessage) m2 = NULL; + + if (!spa_streq(this->modem.path, dbus_message_get_path(m))) + goto finish; +@@ -590,12 +590,12 @@ static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void + call_object->path = strdup(path); + spa_list_append(&this->call_list, &call_object->link); + +- m = dbus_message_new_method_call(MM_DBUS_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "GetAll"); +- if (m == NULL) ++ m2 = dbus_message_new_method_call(MM_DBUS_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "GetAll"); ++ if (m2 == NULL) + goto finish; +- dbus_message_append_args(m, DBUS_TYPE_STRING, &mm_call_interface, DBUS_TYPE_INVALID); ++ dbus_message_append_args(m2, DBUS_TYPE_STRING, &mm_call_interface, DBUS_TYPE_INVALID); + +- call_object->pending = send_with_reply(this->conn, m, mm_get_call_properties_reply, call_object); ++ call_object->pending = send_with_reply(this->conn, m2, mm_get_call_properties_reply, call_object); + if (!call_object->pending) { + spa_log_error(this->log, "dbus call failure"); + goto finish; +-- +2.45.2 + diff --git a/extra-repos/systemd/pipewire/APKBUILD b/extra-repos/systemd/pipewire/APKBUILD new file mode 100644 index 000000000..462a33ace --- /dev/null +++ b/extra-repos/systemd/pipewire/APKBUILD @@ -0,0 +1,261 @@ +# Forked from Alpine to rebuild with systemd support + +pkgname=pipewire +pkgver=9991.0.6 +_pkgver=1.0.6 +pkgrel=6 +_so_ver=0.3 +pkgdesc="Multimedia processing graphs" +url="https://pipewire.org/" +arch="all" +license="LGPL-2.1-or-later" +pkggroups="pipewire" +makedepends=" + alsa-lib-dev + avahi-dev + bash + bluez-dev + dbus-dev + doxygen + eudev-dev + fdk-aac-dev + glib-dev + graphviz + gst-plugins-base-dev + gstreamer-dev + jack-dev + libcamera-dev + libfreeaptx-dev + liblc3-dev + libusb-dev + libx11-dev + lilv-dev + meson + modemmanager-dev + ncurses-dev + pulseaudio-dev + py3-docutils + readline-dev + roc-toolkit-dev + sbc-dev + systemd-dev + vulkan-loader-dev + xmltoman + " +# move regular -dev after -jackdev, to steal files +subpackages=" + $pkgname-dbg + $pkgname-doc + $pkgname-alsa + $pkgname-pulse + $pkgname-jack + $pkgname-jack-dev:jackdev + $pkgname-dev + gst-plugin-pipewire:gst_plugin + $pkgname-zeroconf + $pkgname-spa-bluez + $pkgname-spa-vulkan + $pkgname-tools + $pkgname-spa-tools:spa_tools + $pkgname-lang + " +install="$pkgname.post-upgrade $pkgname.post-install" +source="https://gitlab.freedesktop.org/PipeWire/pipewire/-/archive/$_pkgver/pipewire-$_pkgver.tar.gz + pipewire.desktop + pipewire-launcher.sh + 0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch + " +builddir="$srcdir/$pkgname-$_pkgver" + +case "$CARCH" in + s390x) + # libldac not available for big endian + ;; + *) + makedepends="$makedepends libldac-dev" + ;; +esac + +case "$CARCH" in + ppc64le|s390x|riscv64) + # no webrtc-audio-processing + ;; + *) + makedepends="$makedepends webrtc-audio-processing-1-dev" + subpackages="$subpackages $pkgname-echo-cancel:echo_cancel" + ;; +esac + +# put libs last to steal residual files taken by some prior extras +subpackages="$subpackages $pkgname-libs" + +build() { + CFLAGS="$CFLAGS -O2" \ + CXXFLAGS="$CXXFLAGS -O2" \ + CPPFLAGS="$CPPFLAGS -O2" \ + abuild-meson \ + -Db_lto=true \ + -Dlibjack-path=/usr/lib \ + -Dlibv4l2-path=/usr/lib \ + -Ddocs=disabled \ + -Dman=enabled \ + -Dgstreamer=enabled \ + -Dexamples=enabled \ + -Dffmpeg=disabled \ + -Djack-devel=true \ + -Dsystemd=enabled\ + -Dvulkan=enabled \ + -Dsdl2=disabled \ + -Dlv2=enabled \ + -Dlibcamera=enabled \ + -Droc=enabled \ + -Dbluez5-codec-lc3=enabled \ + -Dbluez5-backend-native-mm=enabled \ + -Dsession-managers=[] \ + . output + meson compile -C output +} + +check() { + # disable tests on armv7, this is run via qemu+binfmt on pmOS CI and fails. + # See: https://gitlab.com/postmarketOS/pmaports/-/merge_requests/5142#note_1969455333 + [ "$CARCH" = "armv7" ] && return + + meson test --no-rebuild --print-errorlogs -C output +} + +package() { + DESTDIR="$pkgdir" meson install --no-rebuild -C output + + install -Dm644 "$srcdir"/pipewire.desktop -t "$pkgdir"/etc/xdg/autostart/ + install -Dm755 "$srcdir"/pipewire-launcher.sh "$pkgdir"/usr/libexec/pipewire-launcher +} + +alsa() { + pkgdesc="ALSA support for pipewire" + replaces="$pkgname" # for backward compatibility + + amove usr/lib/alsa-lib + amove usr/share/alsa/alsa.conf.d + + install -d "$subpkgdir"/etc/alsa/conf.d + for i in "$subpkgdir"/usr/share/alsa/alsa.conf.d/*.conf; do + ln -s -- "${i#"$subpkgdir"}" "$subpkgdir"/etc/alsa/conf.d/ + done +} + +pulse() { + pkgdesc="Pulseaudio support for pipewire" + depends=" + pipewire-session-manager + pulseaudio-utils + " + provides="pulseaudio=$pkgver-r$pkgrel pulseaudio-bluez=$pkgver-r$pkgrel" + provider_priority=1 + + amove usr/bin/pipewire-pulse + amove usr/lib/pipewire-$_so_ver/libpipewire-module-protocol-pulse.so + amove usr/lib/pipewire-$_so_ver/libpipewire-module-pulse-tunnel.so + amove usr/lib/pipewire-$_so_ver/libpipewire-module-filter-chain-lv2.so + amove usr/share/pipewire/pipewire-pulse.conf + amove usr/share/pipewire/pipewire-pulse.conf.avail + amove usr/lib/systemd/user/pipewire-pulse.service + amove usr/lib/systemd/user/pipewire-pulse.socket +} + +jack() { + pkgdesc="JACK support for pipewire" + depends="pipewire-session-manager" + provides="jack=$pkgver-r$pkgrel" + replaces="jack" + + amove usr/lib/libjack*.so.* + amove usr/bin/pw-jack + amove usr/lib/spa-*/jack/libspa-jack.so + amove usr/share/pipewire/jack.conf +} + +gst_plugin() { + pkgdesc="Multimedia graph framework - PipeWire plugin" + depends="pipewire-session-manager gst-plugins-base" + install_if="$pkgname=$pkgver-r$pkgrel gstreamer" + + amove usr/lib/gstreamer-1.0 +} + +echo_cancel() { + pkgdesc="WebRTC-based echo canceller module for PipeWire" + depends="$pkgname=$pkgver-r$pkgrel" + + amove usr/lib/pipewire-$_so_ver/libpipewire-module-echo-cancel.so +} + +zeroconf() { + pkgdesc="$pkgdesc - Zeroconf support" + depends="" + provides="pulseaudio-zeroconf=$pkgver-r$pkgrel" + provider_priority=1 + + amove usr/lib/pipewire-$_so_ver/libpipewire-module-zeroconf-discover.so + amove usr/lib/pipewire-$_so_ver/libpipewire-module-raop-*.so +} + +bluez() { + pkgdesc="PipeWire BlueZ5 SPA plugin (Bluetooth)" + depends="" + replaces="$pkgname" # for backward compatibility + + amove usr/lib/spa-*/bluez5 +} + +vulkan() { + pkgdesc="PipeWire Vulkan SPA plugin" + depends="" + + amove usr/lib/spa-*/vulkan +} + +tools() { + pkgdesc="PipeWire tools" + depends="$pkgname=$pkgver-r$pkgrel" + replaces="$pkgname" # for backward compatibility + + amove usr/bin/pw-* +} + +spa_tools() { + pkgdesc="PipeWire SPA tools" + depends="" + replaces="$pkgname" # for backward compatibility + + amove usr/bin/spa-* +} + +jackdev() { + pkgdesc="JACK development files (from pipewire)" + provides="jack-dev=$pkgver-r$pkgrel" + + amove usr/lib/libjack*.so + amove usr/include/jack + amove usr/lib/pkgconfig/jack.pc +} + +libs() { + default_libs + + # the libraries must be paired with the client config and the plugins, + # see: + # https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3296 + # https://bugs.archlinux.org/task/78813 + amove \ + usr/share/pipewire/client*.conf* \ + usr/lib/pipewire-*/ \ + usr/lib/spa-*/ +} + +sha512sums=" +70bec82280a99ddc014d70d825bbbbd69112b5a855f6cb19196eb2f4c52cff7f8f1a6b005a484a3a913a88ead9897745850627177f937c703f8f7272edc00ae6 pipewire-1.0.6.tar.gz +b70b05151bcf4b7f13d68b2731d789b9c062fadfcb91f4ed6bdb0d495390b0010f57034fb115a053e1459c7d9ea27523ca1c0c69639aeeb96c17ebac8dfc5b57 pipewire.desktop +6f4322d306bef346187778fc0975d608fdd37d4c8e08815a0aed28ef7e07c3f21d6a80b70743d0f867bdc237f5e1dc28131c778e7a45e363e5677668ce7acdb1 pipewire-launcher.sh +d48159d661f1c87d3fc23d5030def99398e7fddb82bf3b7db11490b9ac0f30d57b4173d529025d7da695f2a8ef5c3f82f532c2be13c032a320e9b6bd9c2c7c55 0001-spa-bluez-fix-crash-when-receiving-signal-from-modem.patch +" diff --git a/extra-repos/systemd/pipewire/pipewire-launcher.sh b/extra-repos/systemd/pipewire/pipewire-launcher.sh new file mode 100644 index 000000000..946cf1cee --- /dev/null +++ b/extra-repos/systemd/pipewire/pipewire-launcher.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# We need to kill any existing pipewire instance to restore sound +pkill -u "${USER}" -fx /usr/bin/pipewire-pulse 1>/dev/null 2>&1 +pkill -u "${USER}" -fx /usr/bin/pipewire-media-session 1>/dev/null 2>&1 +pkill -u "${USER}" -fx /usr/bin/wireplumber 1>/dev/null 2>&1 +pkill -u "${USER}" -fx /usr/bin/pipewire 1>/dev/null 2>&1 + +exec /usr/bin/pipewire & + +# wait for pipewire to start before attempting to start related daemons +while [ "$(pgrep -f /usr/bin/pipewire)" = "" ]; do + sleep 1 +done + +if [ -x /usr/bin/wireplumber ]; then + exec /usr/bin/wireplumber & +elif [ -x /usr/bin/pipewire-media-session ]; then + exec /usr/bin/pipewire-media-session & +fi + +[ -f "/usr/share/pipewire/pipewire-pulse.conf" ] && exec /usr/bin/pipewire-pulse & diff --git a/extra-repos/systemd/pipewire/pipewire.desktop b/extra-repos/systemd/pipewire/pipewire.desktop new file mode 100644 index 000000000..d80505003 --- /dev/null +++ b/extra-repos/systemd/pipewire/pipewire.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=Pipewire +Comment=Start Pipewire +Exec=/usr/libexec/pipewire-launcher +Terminal=false +Type=Application +X-KDE-autostart-phase=1 +X-GNOME-HiddenUnderSystemd=true +X-systemd-skip=true diff --git a/extra-repos/systemd/pipewire/pipewire.post-install b/extra-repos/systemd/pipewire/pipewire.post-install new file mode 100644 index 000000000..2b7f10a86 --- /dev/null +++ b/extra-repos/systemd/pipewire/pipewire.post-install @@ -0,0 +1,5 @@ +#!/bin/sh + +addgroup -S pipewire 2>/dev/null + +exit 0 diff --git a/extra-repos/systemd/pipewire/pipewire.post-upgrade b/extra-repos/systemd/pipewire/pipewire.post-upgrade new file mode 100644 index 000000000..9dc5691bc --- /dev/null +++ b/extra-repos/systemd/pipewire/pipewire.post-upgrade @@ -0,0 +1,14 @@ +#!/bin/sh + +ver_old="$2" + +if [ "$(apk version -t "$ver_old" '0.3.33-r3')" = '<' ]; then + cat >&2 <<-EOF + * + * Pipewire bluez5 (Bluetooth) and FFmpeg SPA plugins, ALSA support, pw-* and + * spa-* tools have been moved to subpackages. If you use them, install + * pipewire-spa-bluez, pipewire-spa-ffmpeg, pipewire-alsa, pipewire-tools and/or + * pipewire-spa-tools, repsectively. + * + EOF +fi