summaryrefslogtreecommitdiffstats
path: root/meta-agl-devel
diff options
context:
space:
mode:
Diffstat (limited to 'meta-agl-devel')
-rw-r--r--meta-agl-devel/.gitreview2
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/conf/layer.conf (renamed from meta-agl-devel/meta-html5-framework/conf/layer.conf)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/agl-service-windowmanager_git.bbappend9
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/files/areas.horizontal.json94
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf.bbappend12
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/hdmi-a-1-180.cfg4
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/virtual-landscape.cfg3
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.bb10
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.inc9
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-appfw-html5.bb18
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-profile-graphical-html5.bb23
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium-browser-service.bb (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium-browser-service.bb)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68_git.bb (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68_git.bb)6
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/gn-utils.inc (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/chromium/gn-utils.inc)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr.env (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr.env)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr@.service (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr@.service)0
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/trunc-webapp-roles.patch53
-rw-r--r--meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/wam_git.bb (renamed from meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam_git.bb)8
-rw-r--r--meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform-crosssdk.bbappend3
-rw-r--r--meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform.bbappend3
-rw-r--r--meta-agl-devel/meta-html5-framework/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb26
-rw-r--r--meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam-tinyproxy_git.bb20
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch75
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/agl-service-audiomixer/agl-service-audiomixer_git.bb3
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf10
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf.in17
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl_git.bb9
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire.inc7
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-meson-revert-version-check-to-require-meson-0.47-not.patch30
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-spa-include-install-missing-headers.patch41
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-arm-build-with-mno-unaligned-access.patch (renamed from meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-arm-build-with-mno-unaligned-access.patch)10
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-extensions-implement-Endpoint-ClientEndpoint-interfa.patch1563
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch (renamed from meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0010-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch)81
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-pipewire-cli-add-support-for-printing-endpoint-info-.patch149
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-audioconvert-always-assume-that-output-ports-are-NOT.patch35
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-pipewire-cli-add-command-to-modify-endpoint-control-.patch124
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-module-access-add-same-sec-label-mode.patch94
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-alsa-pcm-call-reuse_buffers-when-resetting-the-state.patch30
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-logger-print-timestamps-on-logged-messages.patch52
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0007-alsa-make-corrections-on-the-timeout-based-on-how-fa.patch130
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0008-audio-dsp-allow-mode-to-be-set-with-a-property.patch45
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0009-audioconvert-do-setup-internal-links-and-buffers-als.patch55
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0011-gst-pwaudioringbuffer-make-the-buffer-size-sensitive.patch60
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0012-gst-pwaudioringbuffer-request-pause-play-on-the-appr.patch76
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0013-gst-pwaudioringbuffer-wait-only-for-STREAM_STATE_CON.patch35
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0014-gst-pwaudiosink-set-the-default-latency-time-buffer-.patch37
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0015-audioconvert-fmtconvert-assume-F32-on-the-other-port.patch44
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0016-gst-pwaudioringbuffer-set-node.latency-to-get-schedu.patch41
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0017-connection-move-remaining-data-and-fds.patch61
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0018-protocol-improve-flushing.patch222
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire_git.bb30
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-sink.endpoint10
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-source.endpoint10
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-input-audio.endpoint-link7
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-output-audio.endpoint-link7
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-input-audio.endpoint9
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-output-audio.endpoint9
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-sink.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-source.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-sink.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-source.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-sink.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-source.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-rpi3-audio-sink.endpoint13
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-fiberdyne-amp.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-microchip-mic.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-sink.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-source.endpoint12
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link11
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link11
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/capture.streams3
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/playback.streams31
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf30
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf.in55
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb68
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch28
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb20
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-security/cynagora/cynagora_%.bbappend5
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager/0001-Adapt-smack-rules-to-allow-connections-to-pipewire.patch25
-rw-r--r--meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager_%.bbappend6
-rw-r--r--meta-agl-devel/meta-speech-framework/conf/include/agl-speech-framework.inc3
-rw-r--r--meta-agl-devel/meta-speech-framework/conf/include/agl-voiceagent-alexa.inc6
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac-amazonlite/recipes-wakeword/pryon-lite/pryon-lite.bbappend2
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config/voice-high.json1
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config_1.0.bb20
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config/AlexaAutoCoreEngineConfig.json.in184
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config_1.0.bb40
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0001-remove-library-dependency-copying.patch15
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0005-fix-segmentation-fault-for-release-build-mode.patch33
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0006-fix-event-argument-json.patch183
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/alexa.json14
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service_git.bb25
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend4
-rw-r--r--meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-voiceagent-alexa.bb15
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high-capabilities/agl-service-voice-high-capabilities_git.bb8
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/agl-service-voice-high_git.bb5
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config/voice-high.json1
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config_1.0.bb20
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-core-services.bbappend7
-rw-r--r--meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend5
-rw-r--r--meta-agl-devel/templates/feature/agl-html5-framework/50_bblayers.conf.inc5
-rw-r--r--meta-agl-devel/templates/feature/agl-html5-framework/README_feature_agl-html5-framework.md9
-rw-r--r--meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_bblayers.conf.inc5
-rw-r--r--meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_local.conf.inc3
-rw-r--r--meta-agl-devel/templates/feature/agl-profile-graphical-html5/README_feature_agl-profile-graphical-html5.md8
-rw-r--r--meta-agl-devel/templates/feature/agl-profile-graphical-html5/included.dep1
-rw-r--r--meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_bblayers.conf.inc6
-rw-r--r--meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_local.conf.inc1
-rw-r--r--meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/README_feature_agl-voiceagent-alexa-wakeword.md10
-rw-r--r--meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/included.dep1
111 files changed, 1549 insertions, 3038 deletions
diff --git a/meta-agl-devel/.gitreview b/meta-agl-devel/.gitreview
index e2b97232..d4a1744e 100644
--- a/meta-agl-devel/.gitreview
+++ b/meta-agl-devel/.gitreview
@@ -2,4 +2,4 @@
host=gerrit.automotivelinux.org
port=29418
project=AGL/meta-agl-devel
-defaultbranch=halibut
+defaultbranch=icefish
diff --git a/meta-agl-devel/meta-html5-framework/conf/layer.conf b/meta-agl-devel/meta-agl-profile-graphical-html5/conf/layer.conf
index 6673b564..6673b564 100644
--- a/meta-agl-devel/meta-html5-framework/conf/layer.conf
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/conf/layer.conf
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/agl-service-windowmanager_git.bbappend b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/agl-service-windowmanager_git.bbappend
new file mode 100644
index 00000000..06f89f69
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/agl-service-windowmanager_git.bbappend
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += " \
+ file://areas.horizontal.json \
+"
+
+do_compile_prepend() {
+ cp ${WORKDIR}/areas.horizontal.json ${S}/conf/areas.json
+}
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/files/areas.horizontal.json b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/files/areas.horizontal.json
new file mode 100644
index 00000000..4b6f0c39
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-apis/agl-service-windowmanager/files/areas.horizontal.json
@@ -0,0 +1,94 @@
+{
+ "areas": [
+ {
+ "name": "fullscreen",
+ "rect": {
+ "x": 0,
+ "y": 0,
+ "w": 1920,
+ "h": 1080
+ }
+ },
+ {
+ "name": "normal.full",
+ "rect": {
+ "x": 218,
+ "y": 0,
+ "w": 1702,
+ "h": 1080
+ }
+ },
+ {
+ "name": "split.main",
+ "rect": {
+ "x": 218,
+ "y": 0,
+ "w": 744,
+ "h": 1080
+ }
+ },
+ {
+ "name": "split.sub",
+ "rect": {
+ "x": 962,
+ "y": 0,
+ "w": 744,
+ "h": 1080
+ }
+ },
+ {
+ "name": "software_keyboard",
+ "rect": {
+ "x": 962,
+ "y": 0,
+ "w": 744,
+ "h": 1080
+ }
+ },
+ {
+ "name": "restriction.normal",
+ "rect": {
+ "x": 218,
+ "y": 0,
+ "w": 1488,
+ "h": 1080
+ }
+ },
+ {
+ "name": "restriction.split.main",
+ "rect": {
+ "x": 218,
+ "y": 0,
+ "w": 744,
+ "h": 1080
+ }
+ },
+ {
+ "name": "restriction.split.sub",
+ "rect": {
+ "x": 962,
+ "y": 0,
+ "w": 744,
+ "h": 1080
+ }
+ },
+ {
+ "name": "on_screen",
+ "rect": {
+ "x": 218,
+ "y": 0,
+ "w": 1488,
+ "h": 1080
+ }
+ },
+ {
+ "name": "remote.fullscreen",
+ "rect": {
+ "x": 0,
+ "y": 0,
+ "w": 720,
+ "h": 640
+ }
+ }
+ ]
+}
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf.bbappend b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf.bbappend
new file mode 100644
index 00000000..2c5201aa
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf.bbappend
@@ -0,0 +1,12 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_remove = " \
+ file://hdmi-a-1-270.cfg \
+ file://hdmi-a-1-90.cfg \
+ file://virtual.cfg \
+"
+
+SRC_URI += " \
+ file://hdmi-a-1-180.cfg \
+ file://virtual-landscape.cfg \
+"
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/hdmi-a-1-180.cfg b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/hdmi-a-1-180.cfg
new file mode 100644
index 00000000..59e2c2db
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/hdmi-a-1-180.cfg
@@ -0,0 +1,4 @@
+# A display is connected to HDMI-A-1
+[output]
+name=HDMI-A-1
+transform=0
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/virtual-landscape.cfg b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/virtual-landscape.cfg
new file mode 100644
index 00000000..d6925363
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-graphics/wayland/weston-ini-conf/virtual-landscape.cfg
@@ -0,0 +1,3 @@
+[output]
+name=Virtual-1
+mode=1920x1080
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.bb
new file mode 100644
index 00000000..0ec6829e
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.bb
@@ -0,0 +1,10 @@
+SUMMARY = "An image containing all packages required to run web applications"
+
+require agl-image-graphical-html5.inc
+
+LICENSE = "MIT"
+
+IMAGE_INSTALL_append = "\
+ packagegroup-agl-profile-graphical-html5 \
+ "
+
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.inc b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.inc
new file mode 100644
index 00000000..21f3b19a
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/images/agl-image-graphical-html5.inc
@@ -0,0 +1,9 @@
+require recipes-platform/images/agl-image-minimal.inc
+
+IMAGE_FEATURES += "splash"
+
+IMAGE_FEATURES += "${@bb.utils.contains('DISTRO_FEATURES', 'agl-devel', 'ssh-server-dropbear' , '', d)}"
+
+inherit distro_features_check
+
+REQUIRED_DISTRO_FEATURES = "wayland"
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-appfw-html5.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-appfw-html5.bb
new file mode 100644
index 00000000..cc9ed3d6
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-appfw-html5.bb
@@ -0,0 +1,18 @@
+SUMMARY = "AGL web runtime packages"
+DESCRIPTION = "Specific packages for the AGL web runtime (minus profile-graphical)"
+
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-appfw-html5 \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+# add packages for WAM
+RDEPENDS_${PN} += " \
+ chromium-browser-service \
+ wam \
+ "
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-profile-graphical-html5.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-profile-graphical-html5.bb
new file mode 100644
index 00000000..20275014
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-platform/packagegroups/packagegroup-agl-profile-graphical-html5.bb
@@ -0,0 +1,23 @@
+SUMMARY = "AGL web runtime profile"
+DESCRIPTION = "The full set of packages required for AGL web runtime"
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-profile-graphical-html5 \
+ profile-graphical-html5 \
+ "
+
+ALLOW_EMPTY_${PN} = "1"
+
+RDEPENDS_${PN} += "\
+ packagegroup-agl-profile-graphical \
+ packagegroup-agl-appfw-html5 \
+"
+
+RDEPENDS_${PN} += "\
+ agl-login-manager \
+ "
+
+RDEPENDS_profile-graphical-html5 = "${PN}"
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium-browser-service.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium-browser-service.bb
index 2686c7c8..2686c7c8 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium-browser-service.bb
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium-browser-service.bb
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch
index 485766b0..485766b0 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68/v8-qemu-wrapper.patch
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68_git.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68_git.bb
index e23e53ee..100eb628 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/chromium68_git.bb
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/chromium68_git.bb
@@ -19,11 +19,11 @@ DEPENDS = "virtual/gettext wayland wayland-native pixman freetype glib-2.0 fontc
PROVIDES = "${BROWSER_APPLICATION}"
SRC_URI = "\
- git://github.com/webosose/${PN};branch=@39.agl.guppy;protocol=https;rev=${SRCREV_chromium68} \
- git://github.com/webosose/v8;destsuffix=git/src/v8;rev=${SRCREV_v8} \
+ git://github.com/webosose/${PN};branch=@39.agl.guppy;protocol=https;rev=${SRCREV_chromium68};name=chromium68 \
+ git://github.com/webosose/v8;destsuffix=git/src/v8;rev=${SRCREV_v8};name=v8 \
file://v8-qemu-wrapper.patch \
"
-SRCREV_chromium68 = "3169198da53cbb842e504e91473e021a6b07bcc0"
+SRCREV_chromium68 = "5ebefe83ead91ce6fd2ac8ff9699b848a83ee0ff"
SRCREV_v8 = "1e3af71f1ff3735e8a5b639c48dfca63a7b8a647"
# we don't include SRCPV in PV, so we have to manually include SRCREVs in do_fetch vardeps
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/gn-utils.inc b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/gn-utils.inc
index 0fd55a63..0fd55a63 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/chromium/gn-utils.inc
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/chromium/gn-utils.inc
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr.env b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr.env
index c8ddc517..c8ddc517 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr.env
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr.env
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr@.service b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr@.service
index 09573a76..09573a76 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/files/WebAppMgr@.service
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/WebAppMgr@.service
diff --git a/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/trunc-webapp-roles.patch b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/trunc-webapp-roles.patch
new file mode 100644
index 00000000..63ad8208
--- /dev/null
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/files/trunc-webapp-roles.patch
@@ -0,0 +1,53 @@
+From 870dd9c0e80d2f7ce843399f606299629ae7b570 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= <jaragunde@igalia.com>
+Date: Thu, 23 Jan 2020 11:57:23 +0100
+Subject: [PATCH] Set webapp roles that are max 12 characters long.
+
+This is a workaround for SPEC-3127. To prevent repeated roles as much
+as possible, I'm using the appid as a basis instead of "Webapp-" +
+host + port, which has many chances to be redundant in the first 12
+chars.
+
+Bug-AGL: SPEC-3127
+---
+ src/agl/WebRuntimeAGL.cpp | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/src/agl/WebRuntimeAGL.cpp b/src/agl/WebRuntimeAGL.cpp
+index a919759..baa2708 100644
+--- a/src/agl/WebRuntimeAGL.cpp
++++ b/src/agl/WebRuntimeAGL.cpp
+@@ -162,7 +162,6 @@ int WebAppLauncherRuntime::run(int argc, const char** argv) {
+ bool isWaitHostService = isWaitForHostService(args);
+ m_id = getAppId(args);
+ m_url = getAppUrl(args);
+- m_role = "WebApp";
+
+ if(isWaitHostService) {
+ while(!WebAppManagerServiceAGL::instance()->isHostServiceRunning()) {
+@@ -220,15 +219,9 @@ bool WebAppLauncherRuntime::init() {
+ if (n != std::string::npos) {
+ std::string sport = authority.substr(n+1);
+ m_host = authority.substr(0, n);
+- m_role.push_back('-');
+- m_role.append(m_host);
+- m_role.push_back('-');
+- m_role.append(sport);
+ m_port = stringTo<int>(sport);
+ } else {
+ m_host = authority;
+- m_role.push_back('-');
+- m_role.append(m_host);
+ }
+ }
+
+@@ -265,6 +258,9 @@ bool WebAppLauncherRuntime::init() {
+ m_role = "homescreen";
+ else if (m_id.rfind("webapps-homescreen", 0) == 0)
+ m_role = "homescreen";
++ else {
++ m_role = m_id.substr(0,12);
++ }
+
+ LOG_DEBUG("id=[%s], name=[%s], role=[%s], url=[%s], host=[%s], port=%d, token=[%s]",
+ m_id.c_str(), m_name.c_str(), m_role.c_str(), m_url.c_str(),
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam_git.bb b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/wam_git.bb
index 16737cab..2ccd6e63 100644
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam_git.bb
+++ b/meta-agl-devel/meta-agl-profile-graphical-html5/recipes-wam/wam/wam_git.bb
@@ -19,12 +19,13 @@ PROVIDES += "virtual/webruntime"
RPROVIDES_${PN} += "virtual/webruntime"
SRC_URI = "\
- git://github.com/webosose/${PN}.git;branch=@6.agl.guppy;protocol=https \
+ git://github.com/webosose/${PN}.git;branch=@6.agl.icefish;protocol=https \
file://WebAppMgr@.service \
file://WebAppMgr.env \
+ file://trunc-webapp-roles.patch \
"
S = "${WORKDIR}/git"
-SRCREV = "8271e13578b92b192cef1d1ac6577bc3699518a4"
+SRCREV = "060043b40ffc9fafcf94eec832c2158e81c74f32"
do_install_append() {
install -d ${D}${sysconfdir}/wam
@@ -38,7 +39,6 @@ do_install_append() {
ln -sf ../WebAppMgr@.service ${D}${systemd_system_unitdir}/afm-user-session@.target.wants/
}
-RDEPENDS_${PN} += "wam-tinyproxy"
FILES_${PN} += "${sysconfdir}/init ${sysconfdir}/wam ${libdir}/webappmanager/plugins/*.so ${systemd_system_unitdir}"
CXXFLAGS_append_agl-devel = " -DAGL_DEVEL"
@@ -48,4 +48,4 @@ do_install_append_agl-devel() {
install -d ${D}${localstatedir}/agl-devel/preferences
touch ${D}${localstatedir}/agl-devel/preferences/debug_system_apps
touch ${D}${localstatedir}/agl-devel/preferences/devmode_enabled
-} \ No newline at end of file
+}
diff --git a/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform-crosssdk.bbappend b/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform-crosssdk.bbappend
deleted file mode 100644
index d5d978dd..00000000
--- a/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform-crosssdk.bbappend
+++ /dev/null
@@ -1,3 +0,0 @@
-IMAGE_INSTALL_append += "\
- packagegroup-agl-demo-platform-html5 \
- "
diff --git a/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform.bbappend b/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform.bbappend
deleted file mode 100644
index d5d978dd..00000000
--- a/meta-agl-devel/meta-html5-framework/recipes-platform/images/agl-demo-platform.bbappend
+++ /dev/null
@@ -1,3 +0,0 @@
-IMAGE_INSTALL_append += "\
- packagegroup-agl-demo-platform-html5 \
- "
diff --git a/meta-agl-devel/meta-html5-framework/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb b/meta-agl-devel/meta-html5-framework/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb
deleted file mode 100644
index c4e3c0d7..00000000
--- a/meta-agl-devel/meta-html5-framework/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb
+++ /dev/null
@@ -1,26 +0,0 @@
-SUMMARY = "The software for DEMO platform of AGL IVI profile"
-DESCRIPTION = "A set of packages belong to AGL Demo Platform"
-
-LICENSE = "MIT"
-
-inherit packagegroup
-
-PACKAGES = "\
- packagegroup-agl-demo-platform-html5 \
- "
-
-ALLOW_EMPTY_${PN} = "1"
-
-RDEPENDS_${PN} += "\
- packagegroup-agl-image-ivi \
- "
-
-# add packages for demo platform (include demo apps) here
-RDEPENDS_${PN} += " \
- "
-
-# add packages for WAM
-RDEPENDS_${PN} += " \
- chromium-browser-service \
- wam \
- "
diff --git a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam-tinyproxy_git.bb b/meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam-tinyproxy_git.bb
deleted file mode 100644
index 25a6ed2d..00000000
--- a/meta-agl-devel/meta-html5-framework/recipes-wam/wam/wam-tinyproxy_git.bb
+++ /dev/null
@@ -1,20 +0,0 @@
-SUMMARY = "Lightweight http(s) proxy daemon"
-HOMEPAGE = "https://tinyproxy.github.io/"
-LICENSE = "GPLv2"
-LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
-
-SRC_URI = "git://github.com/Igalia/${PN}.git;branch=wam-proxy;protocol=https"
-S = "${WORKDIR}/git"
-SRCREV = "ab1b5c5a53960afd91d50b1f11e339f653602de8"
-
-EXTRA_OECONF += " \
- --enable-filter \
- --enable-transparent \
- --enable-reverse \
- --enable-upstream \
- --enable-xtinyproxy \
- "
-
-inherit autotools
-
-FILES_${PN} += "${datadir}/tinyproxy/*"
diff --git a/meta-agl-devel/meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch b/meta-agl-devel/meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch
index 37c03218..6c9a388c 100644
--- a/meta-agl-devel/meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch
+++ b/meta-agl-devel/meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch
@@ -1,4 +1,4 @@
-From 33555a493af67f3acc2129764a1b093aec6254d8 Mon Sep 17 00:00:00 2001
+From f2e6a0a324106b40195f88953e55a355875d2b1b Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Fri, 4 Oct 2019 20:51:24 +0300
Subject: [PATCH] utils: add a gstreamer helper application for interconnection
@@ -24,8 +24,8 @@ Upstream-Status: Inappropriate
---
configure.ac | 7 +
utils/Makefile.am | 20 +++
- utils/gst-helper.c | 379 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 406 insertions(+)
+ utils/gst-helper.c | 432 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 459 insertions(+)
create mode 100644 utils/gst-helper.c
diff --git a/configure.ac b/configure.ac
@@ -76,10 +76,10 @@ index 9057f2c..9790474 100644
+endif
diff --git a/utils/gst-helper.c b/utils/gst-helper.c
new file mode 100644
-index 0000000..1b021ee
+index 0000000..de1d47c
--- /dev/null
+++ b/utils/gst-helper.c
-@@ -0,0 +1,379 @@
+@@ -0,0 +1,432 @@
+/* Bluez-Alsa PipeWire integration GStreamer helper
+ *
+ * Copyright © 2016-2019 Arkadiusz Bokowy
@@ -123,6 +123,9 @@ index 0000000..1b021ee
+ int ba_pcm_ctrl_fd;
+ /* the gstreamer pipelines (sink & source) */
+ GstElement *pipeline[2];
++ /* the queue & pwaudiosink of the sink pipeline */
++ GstElement *queue;
++ GstElement *pwelem;
+};
+
+static struct ba_dbus_ctx dbus_ctx;
@@ -141,11 +144,44 @@ index 0000000..1b021ee
+ main_loop_on = false;
+}
+
++static GstBusSyncReply
++bus_sync_handler(GstBus *bus, GstMessage *message, gpointer user_data)
++{
++ struct worker *w = user_data;
++ GstState s;
++
++ switch (GST_MESSAGE_TYPE (message)) {
++ case GST_MESSAGE_REQUEST_STATE:
++ gst_message_parse_request_state (message, &s);
++
++ debug ("corked: %d", (s == GST_STATE_PAUSED));
++
++ /* drop queue data when corked */
++ g_object_set (w->queue,
++ "leaky", (s == GST_STATE_PAUSED) ? 2 /* downstream */ : 0 /* no */,
++ NULL);
++ gst_element_set_state (w->pwelem, s);
++
++ /* flush the queue when resuming */
++ if (s == GST_STATE_PLAYING) {
++ gst_element_send_event (w->queue, gst_event_new_flush_start ());
++ gst_element_send_event (w->queue, gst_event_new_flush_stop (FALSE));
++ }
++ break;
++ default:
++ break;
++ }
++
++ gst_message_unref (message);
++ return GST_BUS_DROP;
++}
++
+static int
+worker_start_pipeline(struct worker *w, int id, int mode, int profile)
+{
+ GError *gerr = NULL;
+ DBusError err = DBUS_ERROR_INIT;
++ const gchar * role = NULL;
+
+ if (w->pipeline[id])
+ return 0;
@@ -172,9 +208,15 @@ index 0000000..1b021ee
+ "! rawaudioparse use-sink-caps=true ! m. "
+ /* take the mixer output, convert and push to pipewire */
+ "m.src ! capsfilter name=capsf3 ! audioconvert ! audioresample "
-+ "! audio/x-raw,format=F32LE,rate=48000 ! pwaudiosink name=pwelem",
++ "! audio/x-raw,format=F32LE,rate=48000 ! identity sync=true "
++ "! queue name=queue leaky=no max-size-time=0 max-size-buffers=0 max-size-bytes=192000 "
++ "! pwaudiosink name=pwelem",
+ &gerr);
-+ } else if (mode == BA_PCM_FLAG_SOURCE && profile == BA_PCM_FLAG_PROFILE_SCO) {
++
++ /* a2dp is for music, sco is for calls */
++ role = (profile == BA_PCM_FLAG_PROFILE_A2DP) ? "Multimedia" : "Communication";
++ }
++ else if (mode == BA_PCM_FLAG_SOURCE && profile == BA_PCM_FLAG_PROFILE_SCO) {
+ debug("source start");
+ w->pipeline[id] = gst_parse_launch(
+ /* read from pipewire and put the buffers on a leaky queue, which
@@ -183,9 +225,11 @@ index 0000000..1b021ee
+ 9600 bytes = 50ms @ F32LE/1ch/48000
+ */
+ "pwaudiosrc name=pwelem ! audio/x-raw,format=F32LE,rate=48000 "
-+ "! queue leaky=downstream max-size-time=0 max-size-buffers=0 max-size-bytes=9600 "
++ "! queue name=queue leaky=downstream max-size-time=0 max-size-buffers=0 max-size-bytes=9600 "
+ "! audioconvert ! audioresample ! capsfilter name=capsf "
+ "! fdsink name=fdelem", &gerr);
++
++ role = "Communication";
+ }
+
+ if (gerr) {
@@ -198,6 +242,7 @@ index 0000000..1b021ee
+ g_autofree gchar *capsstr = NULL;
+ g_autoptr (GstElement) fdelem = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "fdelem");
+ g_autoptr (GstElement) pwelem = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "pwelem");
++ g_autoptr (GstElement) queue = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "queue");
+ g_autoptr (GstElement) capsf = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf");
+ g_autoptr (GstElement) capsf2 = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf2");
+ g_autoptr (GstElement) capsf3 = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf3");
@@ -208,8 +253,9 @@ index 0000000..1b021ee
+ "rate", G_TYPE_INT, w->ba_pcm.sampling,
+ NULL);
+ g_autoptr (GstStructure) stream_props = gst_structure_new("props",
-+ "media.role", G_TYPE_STRING, "Communication",
-+ "wireplumber.keep-linked", G_TYPE_STRING, "1",
++ "media.role", G_TYPE_STRING, role,
++ "bluealsa.profile", G_TYPE_STRING,
++ (profile == BA_PCM_FLAG_PROFILE_SCO) ? "sco" : "a2dp",
+ NULL);
+
+ g_object_set(capsf, "caps", caps, NULL);
@@ -224,6 +270,13 @@ index 0000000..1b021ee
+ g_object_set(fdelem, "fd", w->ba_pcm_fd, NULL);
+ g_object_set(pwelem, "stream-properties", stream_props, NULL);
+
++ if (mode == BA_PCM_FLAG_SINK) {
++ g_autoptr (GstBus) bus = gst_pipeline_get_bus(GST_PIPELINE(w->pipeline[id]));
++ gst_bus_set_sync_handler(bus, bus_sync_handler, w, NULL);
++ w->queue = queue;
++ w->pwelem = pwelem;
++ }
++
+ gst_element_set_state(w->pipeline[id], GST_STATE_PLAYING);
+ }
+
@@ -460,5 +513,5 @@ index 0000000..1b021ee
+ return ret;
+}
--
-2.23.0
+2.24.0
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/agl-service-audiomixer/agl-service-audiomixer_git.bb b/meta-agl-devel/meta-pipewire/recipes-multimedia/agl-service-audiomixer/agl-service-audiomixer_git.bb
index c4de73e7..2a826119 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/agl-service-audiomixer/agl-service-audiomixer_git.bb
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/agl-service-audiomixer/agl-service-audiomixer_git.bb
@@ -13,4 +13,5 @@ S = "${WORKDIR}/git"
inherit cmake aglwgt pkgconfig
-DEPENDS += "pipewire"
+DEPENDS += "pipewire wireplumber json-c"
+RDEPENDS_${PN} = "agl-service-signal-composer"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf
deleted file mode 100644
index d09ee8ed..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-# daemon config file for PipeWire version "0.2.9"
-# distributed by Automotive Grade Linux
-load-module libpipewire-module-protocol-native
-load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
-load-module libpipewire-module-client-node
-load-module libpipewire-module-access
-load-module libpipewire-module-audio-dsp
-load-module libpipewire-module-link-factory
-load-module libpipewire-module-endpoint
-exec /usr/bin/wireplumber
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf.in b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf.in
new file mode 100644
index 00000000..6c055bcf
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl/pipewire.conf.in
@@ -0,0 +1,17 @@
+# daemon config file for PipeWire version "0.2.9"
+# distributed by Automotive Grade Linux
+
+add-spa-lib audio.convert* audioconvert/libspa-audioconvert
+add-spa-lib api.alsa.* alsa/libspa-alsa
+add-spa-lib api.v4l2.* v4l2/libspa-v4l2
+add-spa-lib api.bluez5.* bluez5/libspa-bluez5
+
+load-module libpipewire-module-protocol-native
+load-module libpipewire-module-spa-node-factory
+load-module libpipewire-module-client-node
+load-module libpipewire-module-client-device
+load-module libpipewire-module-access same-sec-label-mode=1
+load-module libpipewire-module-adapter
+load-module libpipewire-module-link-factory
+load-module libpipewire-module-session-manager
+exec /usr/bin/wireplumber
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl_git.bb b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl_git.bb
index 2bb76f9d..a28c6534 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl_git.bb
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire-conf-agl_git.bb
@@ -8,7 +8,7 @@ LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = " \
- file://pipewire.conf \
+ file://pipewire.conf.in \
file://client.env \
file://server.env \
"
@@ -17,8 +17,11 @@ do_configure[noexec] = "1"
do_compile[noexec] = "1"
do_install_append() {
- # if we are distributing our own configuration file,
- # replace the one installed by pipewire
+ # enable optional features in the config
+ BLUEZ5=${@bb.utils.contains('DISTRO_FEATURES', 'bluez5', '', '#', d)}
+ sed -e "s/#IF_BLUEZ5 /${BLUEZ5}/" ${WORKDIR}/pipewire.conf.in > ${WORKDIR}/pipewire.conf
+
+ # install our custom config
install -d ${D}/${sysconfdir}/pipewire/
install -m 0644 ${WORKDIR}/pipewire.conf ${D}${sysconfdir}/pipewire/pipewire.conf
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire.inc b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire.inc
index e9046e8e..b3081ca4 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire.inc
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire.inc
@@ -19,7 +19,7 @@ DEPENDS = "dbus"
PACKAGECONFIG ??= "\
${@bb.utils.filter('DISTRO_FEATURES', 'systemd', d)} \
${@bb.utils.filter('DISTRO_FEATURES', 'bluez5', d)} \
- alsa audioconvert \
+ alsa audioconvert audiomixer \
pipewire-alsa \
gstreamer \
"
@@ -31,11 +31,14 @@ PACKAGECONFIG[systemd] = "-Dsystemd=true,-Dsystemd=false,systemd"
# SPA plugins
PACKAGECONFIG[alsa] = "-Dalsa=true,-Dalsa=false,udev alsa-lib"
-PACKAGECONFIG[audioconvert] = "-Daudioconvert=true,-Daudioconvert=false,speexdsp"
+PACKAGECONFIG[audioconvert] = "-Daudioconvert=true,-Daudioconvert=false,"
+PACKAGECONFIG[audiomixer] = "-Daudiomixer=true,-Daudiomixer=false,"
PACKAGECONFIG[audiotestsrc] = "-Daudiotestsrc=true,-Daudiotestsrc=false, "
PACKAGECONFIG[bluez5] = "-Dbluez5=true,-Dbluez5=false,bluez5 sbc"
+PACKAGECONFIG[jack] = "-Djack=true,-Djack=false,jack"
PACKAGECONFIG[v4l2] = "-Dv4l2=true,-Dv4l2=false,udev v4l-utils"
PACKAGECONFIG[videotestsrc] = "-Dvideotestsrc=true,-Dvideotestsrc=false, "
+PACKAGECONFIG[vulkan] = "-Dvulkan=true,-Dvulkan=false,vulkan"
# alsa plugin to redirect audio to pipewire
PACKAGECONFIG[pipewire-alsa] = "-Dpipewire-alsa=true,-Dpipewire-alsa=false,alsa-lib"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-meson-revert-version-check-to-require-meson-0.47-not.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-meson-revert-version-check-to-require-meson-0.47-not.patch
new file mode 100644
index 00000000..4e7bb0d4
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-meson-revert-version-check-to-require-meson-0.47-not.patch
@@ -0,0 +1,30 @@
+From 5a249321aa84cd74e3d83bcd555c85fba3cd682d Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Sun, 22 Sep 2019 17:59:19 +0300
+Subject: [PATCH] meson: revert version check to require meson 0.47, not 0.50
+
+meson 0.50 is not really needed, but there are some strange warnings
+if you require an older version; in any case, AGL does not have 0.50
+yet, so let's not fail compilation because of that...
+
+Upstream-Status: Inappropriate [workaround]
+---
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/meson.build b/meson.build
+index 2734b0d2..c9da6b4d 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1,7 +1,7 @@
+ project('pipewire', ['c' ],
+ version : '0.2.9',
+ license : 'MIT',
+- meson_version : '>= 0.50.0',
++ meson_version : '>= 0.47.0',
+ default_options : [ 'warning_level=1',
+ 'c_std=gnu99',
+ 'buildtype=debugoptimized' ])
+--
+2.24.0
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-spa-include-install-missing-headers.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-spa-include-install-missing-headers.patch
deleted file mode 100644
index 5b928117..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0001-spa-include-install-missing-headers.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From dbb6e10df8c2ba9b874eb9350d4cb93c62dba5a9 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Wed, 29 May 2019 12:09:13 +0300
-Subject: [PATCH] spa/include: install missing headers
-
-Upstream-Status: Accepted
----
- spa/include/spa/meson.build | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/spa/include/spa/meson.build b/spa/include/spa/meson.build
-index c9d07659..c079a1a2 100644
---- a/spa/include/spa/meson.build
-+++ b/spa/include/spa/meson.build
-@@ -39,6 +39,7 @@ spa_monitor_headers = [
- 'monitor/device.h',
- 'monitor/monitor.h',
- 'monitor/type-info.h',
-+ 'monitor/utils.h',
- ]
-
- install_headers(spa_monitor_headers,
-@@ -50,6 +51,7 @@ spa_node_headers = [
- 'node/io.h',
- 'node/node.h',
- 'node/type-info.h',
-+ 'node/utils.h',
- ]
-
- install_headers(spa_node_headers,
-@@ -97,6 +99,7 @@ spa_utils_headers = [
- 'utils/dict.h',
- 'utils/hook.h',
- 'utils/list.h',
-+ 'utils/result.h',
- 'utils/ringbuffer.h',
- 'utils/type.h',
- 'utils/type-info.h',
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-arm-build-with-mno-unaligned-access.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-arm-build-with-mno-unaligned-access.patch
index a670e7ff..2077af63 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-arm-build-with-mno-unaligned-access.patch
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-arm-build-with-mno-unaligned-access.patch
@@ -1,19 +1,19 @@
-From 2016605938f02835c75928648e99b25f7248aa5b Mon Sep 17 00:00:00 2001
+From e4b81946baf2d8c08de87088c01a1d87ae4f03d9 Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Mon, 24 Jun 2019 12:19:20 +0300
Subject: [PATCH] arm: build with -mno-unaligned-access
Upstream-Status: Inappropriate [workaround]
-See also https://github.com/PipeWire/pipewire/issues/161
+See also https://gitlab.freedesktop.org/pipewire/pipewire/issues/161
---
meson.build | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/meson.build b/meson.build
-index 81303d27..f3cc6030 100644
+index c9da6b4d..5c121339 100644
--- a/meson.build
+++ b/meson.build
-@@ -50,6 +50,11 @@ if cc.get_id() == 'gcc'
+@@ -52,6 +52,11 @@ if cc.get_id() == 'gcc'
language : 'c')
endif
@@ -26,5 +26,5 @@ index 81303d27..f3cc6030 100644
sse2_args = '-msse2'
ssse3_args = '-mssse3'
--
-2.20.1
+2.24.0
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-extensions-implement-Endpoint-ClientEndpoint-interfa.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-extensions-implement-Endpoint-ClientEndpoint-interfa.patch
deleted file mode 100644
index e49edf49..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0002-extensions-implement-Endpoint-ClientEndpoint-interfa.patch
+++ /dev/null
@@ -1,1563 +0,0 @@
-From 5afe82a430642c2f7e116941709a624b8fd73011 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Thu, 23 May 2019 18:59:05 +0300
-Subject: [PATCH] extensions: implement Endpoint & ClientEndpoint interfaces
-
-The ClientEndpoint interface allows session managers to register
-endpoint objects on pipewire.
-The Endpoint interface allows other clients to interact with
-endpoints provided by the session manager.
-
-Upstream-Status: Pending
----
- src/extensions/client-endpoint.h | 106 ++++
- src/extensions/endpoint.h | 237 +++++++++
- src/extensions/meson.build | 2 +
- src/modules/meson.build | 12 +
- src/modules/module-endpoint.c | 137 +++++
- src/modules/module-endpoint/endpoint-impl.c | 428 ++++++++++++++++
- src/modules/module-endpoint/endpoint-impl.h | 52 ++
- src/modules/module-endpoint/protocol-native.c | 472 ++++++++++++++++++
- src/pipewire/pipewire.c | 2 +
- src/pipewire/type.h | 3 +-
- 10 files changed, 1450 insertions(+), 1 deletion(-)
- create mode 100644 src/extensions/client-endpoint.h
- create mode 100644 src/extensions/endpoint.h
- create mode 100644 src/modules/module-endpoint.c
- create mode 100644 src/modules/module-endpoint/endpoint-impl.c
- create mode 100644 src/modules/module-endpoint/endpoint-impl.h
- create mode 100644 src/modules/module-endpoint/protocol-native.c
-
-diff --git a/src/extensions/client-endpoint.h b/src/extensions/client-endpoint.h
-new file mode 100644
-index 00000000..0389893c
---- /dev/null
-+++ b/src/extensions/client-endpoint.h
-@@ -0,0 +1,106 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef PIPEWIRE_EXT_CLIENT_ENDPOINT_H
-+#define PIPEWIRE_EXT_CLIENT_ENDPOINT_H
-+
-+#include "endpoint.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+struct pw_client_endpoint_proxy;
-+
-+#define PW_VERSION_CLIENT_ENDPOINT 0
-+#define PW_EXTENSION_MODULE_CLIENT_ENDPOINT PIPEWIRE_MODULE_PREFIX "module-endpoint"
-+
-+#define PW_CLIENT_ENDPOINT_PROXY_METHOD_UPDATE 0
-+#define PW_CLIENT_ENDPOINT_PROXY_METHOD_NUM 1
-+
-+struct pw_client_endpoint_proxy_methods {
-+#define PW_VERSION_CLIENT_ENDPOINT_PROXY_METHODS 0
-+ uint32_t version;
-+
-+ /**
-+ * Update endpoint info
-+ */
-+ int (*update) (void *object,
-+#define PW_CLIENT_ENDPOINT_UPDATE_PARAMS (1 << 0)
-+#define PW_CLIENT_ENDPOINT_UPDATE_PARAMS_INCREMENTAL (1 << 1)
-+#define PW_CLIENT_ENDPOINT_UPDATE_INFO (1 << 2)
-+ uint32_t change_mask,
-+ uint32_t n_params,
-+ const struct spa_pod **params,
-+ const struct pw_endpoint_info *info);
-+};
-+
-+static inline int
-+pw_client_endpoint_proxy_update(struct pw_client_endpoint_proxy *p,
-+ uint32_t change_mask,
-+ uint32_t n_params,
-+ const struct spa_pod **params,
-+ struct pw_endpoint_info *info)
-+{
-+ return pw_proxy_do((struct pw_proxy*)p,
-+ struct pw_client_endpoint_proxy_methods, update,
-+ change_mask, n_params, params, info);
-+}
-+
-+#define PW_CLIENT_ENDPOINT_PROXY_EVENT_SET_PARAM 0
-+#define PW_CLIENT_ENDPOINT_PROXY_EVENT_NUM 1
-+
-+struct pw_client_endpoint_proxy_events {
-+#define PW_VERSION_CLIENT_ENDPOINT_PROXY_EVENTS 0
-+ uint32_t version;
-+
-+ /**
-+ * Set a parameter on the endpoint
-+ *
-+ * \param id the parameter id to set
-+ * \param flags extra parameter flags
-+ * \param param the parameter to set
-+ */
-+ void (*set_param) (void *object, uint32_t id, uint32_t flags,
-+ const struct spa_pod *param);
-+};
-+
-+static inline void
-+pw_client_endpoint_proxy_add_listener(struct pw_client_endpoint_proxy *p,
-+ struct spa_hook *listener,
-+ const struct pw_client_endpoint_proxy_events *events,
-+ void *data)
-+{
-+ pw_proxy_add_proxy_listener((struct pw_proxy*)p, listener, events, data);
-+}
-+
-+#define pw_client_endpoint_resource_set_param(r,...) \
-+ pw_resource_notify(r,struct pw_client_endpoint_proxy_events,set_param,__VA_ARGS__)
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif /* PIPEWIRE_EXT_CLIENT_ENDPOINT_H */
-diff --git a/src/extensions/endpoint.h b/src/extensions/endpoint.h
-new file mode 100644
-index 00000000..211c0895
---- /dev/null
-+++ b/src/extensions/endpoint.h
-@@ -0,0 +1,237 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef PIPEWIRE_EXT_ENDPOINT_H
-+#define PIPEWIRE_EXT_ENDPOINT_H
-+
-+#include <spa/utils/defs.h>
-+#include <spa/utils/type-info.h>
-+#include <pipewire/proxy.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+struct pw_endpoint_proxy;
-+
-+#define PW_VERSION_ENDPOINT 0
-+#define PW_EXTENSION_MODULE_ENDPOINT PIPEWIRE_MODULE_PREFIX "module-endpoint"
-+
-+/* extending enum spa_param_type */
-+enum endpoint_param_type {
-+ PW_ENDPOINT_PARAM_EnumControl = 0x1000,
-+ PW_ENDPOINT_PARAM_Control,
-+ PW_ENDPOINT_PARAM_EnumStream,
-+};
-+
-+enum endpoint_param_object_type {
-+ PW_ENDPOINT_OBJECT_ParamControl = PW_TYPE_FIRST + SPA_TYPE_OBJECT_START + 0x1001,
-+ PW_ENDPOINT_OBJECT_ParamStream,
-+};
-+
-+/** properties for PW_ENDPOINT_OBJECT_ParamControl */
-+enum endpoint_param_control {
-+ PW_ENDPOINT_PARAM_CONTROL_START, /**< object id, one of enum endpoint_param_type */
-+ PW_ENDPOINT_PARAM_CONTROL_id, /**< control id (Int) */
-+ PW_ENDPOINT_PARAM_CONTROL_stream_id, /**< stream id (Int) */
-+ PW_ENDPOINT_PARAM_CONTROL_name, /**< control name (String) */
-+ PW_ENDPOINT_PARAM_CONTROL_type, /**< control type (Range) */
-+ PW_ENDPOINT_PARAM_CONTROL_value, /**< control value */
-+};
-+
-+/** properties for PW_ENDPOINT_OBJECT_ParamStream */
-+enum endpoint_param_stream {
-+ PW_ENDPOINT_PARAM_STREAM_START, /**< object id, one of enum endpoint_param_type */
-+ PW_ENDPOINT_PARAM_STREAM_id, /**< stream id (Int) */
-+ PW_ENDPOINT_PARAM_STREAM_name, /**< stream name (String) */
-+};
-+
-+static const struct spa_type_info endpoint_param_type_info[] = {
-+ { PW_ENDPOINT_PARAM_EnumControl, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ID_BASE "EnumControl", NULL },
-+ { PW_ENDPOINT_PARAM_Control, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ID_BASE "Control", NULL },
-+ { PW_ENDPOINT_PARAM_EnumStream, SPA_TYPE_Int, SPA_TYPE_INFO_PARAM_ID_BASE "EnumStream", NULL },
-+ { 0, 0, NULL, NULL },
-+};
-+
-+#define PW_ENDPOINT_TYPE_INFO_ParamControl SPA_TYPE_INFO_PARAM_BASE "ParamControl"
-+#define PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE PW_ENDPOINT_TYPE_INFO_ParamControl ":"
-+
-+static const struct spa_type_info endpoint_param_control_info[] = {
-+ { PW_ENDPOINT_PARAM_CONTROL_START, SPA_TYPE_Id, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE, spa_type_param, },
-+ { PW_ENDPOINT_PARAM_CONTROL_id, SPA_TYPE_Int, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE "id", NULL },
-+ { PW_ENDPOINT_PARAM_CONTROL_stream_id, SPA_TYPE_Int, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE "streamId", NULL },
-+ { PW_ENDPOINT_PARAM_CONTROL_name, SPA_TYPE_String, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE "name", NULL },
-+ { PW_ENDPOINT_PARAM_CONTROL_type, SPA_TYPE_Pod, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE "type", NULL },
-+ { PW_ENDPOINT_PARAM_CONTROL_value, SPA_TYPE_Struct, PW_ENDPOINT_TYPE_INFO_PARAM_CONTROL_BASE "value", NULL },
-+ { 0, 0, NULL, NULL },
-+};
-+
-+#define PW_ENDPOINT_TYPE_INFO_ParamStream SPA_TYPE_INFO_PARAM_BASE "ParamStream"
-+#define PW_ENDPOINT_TYPE_INFO_PARAM_STREAM_BASE PW_ENDPOINT_TYPE_INFO_ParamStream ":"
-+
-+static const struct spa_type_info endpoint_param_stream_info[] = {
-+ { PW_ENDPOINT_PARAM_STREAM_START, SPA_TYPE_Id, PW_ENDPOINT_TYPE_INFO_PARAM_STREAM_BASE, spa_type_param, },
-+ { PW_ENDPOINT_PARAM_STREAM_id, SPA_TYPE_Int, PW_ENDPOINT_TYPE_INFO_PARAM_STREAM_BASE "id", NULL },
-+ { PW_ENDPOINT_PARAM_STREAM_name, SPA_TYPE_String, PW_ENDPOINT_TYPE_INFO_PARAM_STREAM_BASE "name", NULL },
-+ { 0, 0, NULL, NULL },
-+};
-+
-+static const struct spa_type_info endpoint_param_object_type_info[] = {
-+ { PW_ENDPOINT_OBJECT_ParamControl, SPA_TYPE_Object, SPA_TYPE_INFO_OBJECT_BASE "ParamControl", endpoint_param_control_info, },
-+ { PW_ENDPOINT_OBJECT_ParamStream, SPA_TYPE_Object, SPA_TYPE_INFO_OBJECT_BASE "ParamStream", endpoint_param_stream_info },
-+ { 0, 0, NULL, NULL },
-+};
-+
-+struct pw_endpoint_info {
-+ uint32_t id; /**< id of the global */
-+#define PW_ENDPOINT_CHANGE_MASK_PARAMS (1 << 0)
-+#define PW_ENDPOINT_CHANGE_MASK_PROPS (1 << 1)
-+ uint32_t change_mask; /**< bitfield of changed fields since last call */
-+ uint32_t n_params; /**< number of items in \a params */
-+ struct spa_param_info *params; /**< parameters */
-+ struct spa_dict *props; /**< extra properties */
-+};
-+
-+#define PW_ENDPOINT_PROXY_METHOD_SUBSCRIBE_PARAMS 0
-+#define PW_ENDPOINT_PROXY_METHOD_ENUM_PARAMS 1
-+#define PW_ENDPOINT_PROXY_METHOD_SET_PARAM 2
-+#define PW_ENDPOINT_PROXY_METHOD_NUM 3
-+
-+struct pw_endpoint_proxy_methods {
-+#define PW_VERSION_ENDPOINT_PROXY_METHODS 0
-+ uint32_t version;
-+
-+ /**
-+ * Subscribe to parameter changes
-+ *
-+ * Automatically emit param events for the given ids when
-+ * they are changed.
-+ *
-+ * \param ids an array of param ids
-+ * \param n_ids the number of ids in \a ids
-+ */
-+ int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
-+
-+ /**
-+ * Enumerate endpoint parameters
-+ *
-+ * Start enumeration of endpoint parameters. For each param, a
-+ * param event will be emited.
-+ *
-+ * \param seq a sequence number to place in the reply
-+ * \param id the parameter id to enum or SPA_ID_INVALID for all
-+ * \param start the start index or 0 for the first param
-+ * \param num the maximum number of params to retrieve
-+ * \param filter a param filter or NULL
-+ */
-+ int (*enum_params) (void *object, int seq,
-+ uint32_t id, uint32_t start, uint32_t num,
-+ const struct spa_pod *filter);
-+
-+ /**
-+ * Set a parameter on the endpoint
-+ *
-+ * \param id the parameter id to set
-+ * \param flags extra parameter flags
-+ * \param param the parameter to set
-+ */
-+ int (*set_param) (void *object, uint32_t id, uint32_t flags,
-+ const struct spa_pod *param);
-+};
-+
-+static inline int
-+pw_endpoint_proxy_subscribe_params(struct pw_endpoint_proxy *p, uint32_t *ids, uint32_t n_ids)
-+{
-+ return pw_proxy_do((struct pw_proxy*)p, struct pw_endpoint_proxy_methods,
-+ subscribe_params, ids, n_ids);
-+}
-+
-+static inline int
-+pw_endpoint_proxy_enum_params(struct pw_endpoint_proxy *p, int seq,
-+ uint32_t id, uint32_t start, uint32_t num,
-+ const struct spa_pod *filter)
-+{
-+ return pw_proxy_do((struct pw_proxy*)p, struct pw_endpoint_proxy_methods,
-+ enum_params, seq, id, start, num, filter);
-+}
-+
-+static inline int
-+pw_endpoint_proxy_set_param(struct pw_endpoint_proxy *p, uint32_t id,
-+ uint32_t flags, const struct spa_pod *param)
-+{
-+ return pw_proxy_do((struct pw_proxy*)p, struct pw_endpoint_proxy_methods,
-+ set_param, id, flags, param);
-+}
-+
-+#define PW_ENDPOINT_PROXY_EVENT_INFO 0
-+#define PW_ENDPOINT_PROXY_EVENT_PARAM 1
-+#define PW_ENDPOINT_PROXY_EVENT_NUM 2
-+
-+struct pw_endpoint_proxy_events {
-+#define PW_VERSION_ENDPOINT_PROXY_EVENTS 0
-+ uint32_t version;
-+
-+ /**
-+ * Notify endpoint info
-+ *
-+ * \param info info about the endpoint
-+ */
-+ void (*info) (void *object, const struct pw_endpoint_info * info);
-+
-+ /**
-+ * Notify an endpoint param
-+ *
-+ * Event emited as a result of the enum_params method.
-+ *
-+ * \param seq the sequence number of the request
-+ * \param id the param id
-+ * \param index the param index
-+ * \param next the param index of the next param
-+ * \param param the parameter
-+ */
-+ void (*param) (void *object, int seq, uint32_t id,
-+ uint32_t index, uint32_t next,
-+ const struct spa_pod *param);
-+};
-+
-+static inline void
-+pw_endpoint_proxy_add_listener(struct pw_endpoint_proxy *p,
-+ struct spa_hook *listener,
-+ const struct pw_endpoint_proxy_events *events,
-+ void *data)
-+{
-+ pw_proxy_add_proxy_listener((struct pw_proxy*)p, listener, events, data);
-+}
-+
-+#define pw_endpoint_resource_info(r,...) \
-+ pw_resource_notify(r,struct pw_endpoint_proxy_events,info,__VA_ARGS__)
-+#define pw_endpoint_resource_param(r,...) \
-+ pw_resource_notify(r,struct pw_endpoint_proxy_events,param,__VA_ARGS__)
-+
-+#ifdef __cplusplus
-+} /* extern "C" */
-+#endif
-+
-+#endif /* PIPEWIRE_EXT_ENDPOINT_H */
-diff --git a/src/extensions/meson.build b/src/extensions/meson.build
-index a7f5d3cb..9f690caf 100644
---- a/src/extensions/meson.build
-+++ b/src/extensions/meson.build
-@@ -1,5 +1,7 @@
- pipewire_ext_headers = [
-+ 'client-endpoint.h',
- 'client-node.h',
-+ 'endpoint.h',
- 'protocol-native.h',
- ]
-
-diff --git a/src/modules/meson.build b/src/modules/meson.build
-index 98bc3864..572f1b6b 100644
---- a/src/modules/meson.build
-+++ b/src/modules/meson.build
-@@ -37,6 +37,18 @@ pipewire_module_client_node = shared_library('pipewire-module-client-node',
- dependencies : [mathlib, dl_lib, pipewire_dep],
- )
-
-+pipewire_module_endpoint = shared_library('pipewire-module-endpoint',
-+ [ 'module-endpoint.c',
-+ 'module-endpoint/endpoint-impl.c',
-+ 'module-endpoint/protocol-native.c',
-+ ],
-+ c_args : pipewire_module_c_args,
-+ include_directories : [configinc, spa_inc],
-+ install : true,
-+ install_dir : modules_install_dir,
-+ dependencies : [mathlib, dl_lib, pipewire_dep],
-+)
-+
- pipewire_module_link_factory = shared_library('pipewire-module-link-factory',
- [ 'module-link-factory.c' ],
- c_args : pipewire_module_c_args,
-diff --git a/src/modules/module-endpoint.c b/src/modules/module-endpoint.c
-new file mode 100644
-index 00000000..d830de1b
---- /dev/null
-+++ b/src/modules/module-endpoint.c
-@@ -0,0 +1,137 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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 "config.h"
-+
-+#include "module-endpoint/endpoint-impl.h"
-+
-+struct pw_protocol *pw_protocol_native_ext_endpoint_init(struct pw_core *core);
-+
-+static const struct spa_dict_item module_props[] = {
-+ { PW_MODULE_PROP_AUTHOR, "George Kiagiadakis <george.kiagiadakis@collabora.com>" },
-+ { PW_MODULE_PROP_DESCRIPTION, "Allows clients to interract with session manager endpoints" },
-+ { PW_MODULE_PROP_VERSION, PACKAGE_VERSION },
-+};
-+
-+struct factory_data {
-+ struct pw_factory *this;
-+ struct pw_properties *properties;
-+
-+ struct pw_module *module;
-+ struct spa_hook module_listener;
-+};
-+
-+static void *create_object(void *_data,
-+ struct pw_resource *resource,
-+ uint32_t type,
-+ uint32_t version,
-+ struct pw_properties *properties,
-+ uint32_t new_id)
-+{
-+ void *result;
-+ struct pw_resource *endpoint_resource;
-+ struct pw_global *parent;
-+ struct pw_client *client = pw_resource_get_client(resource);
-+
-+ endpoint_resource = pw_resource_new(client, new_id, PW_PERM_RWX, type, version, 0);
-+ if (endpoint_resource == NULL)
-+ goto no_mem;
-+
-+ parent = pw_client_get_global(client);
-+
-+ result = pw_client_endpoint_new(endpoint_resource, parent, properties);
-+ if (result == NULL)
-+ goto no_mem;
-+
-+ return result;
-+
-+ no_mem:
-+ pw_log_error("can't create endpoint");
-+ pw_resource_error(resource, -ENOMEM, "can't create endpoint: no memory");
-+ if (properties)
-+ pw_properties_free(properties);
-+ return NULL;
-+}
-+
-+static const struct pw_factory_implementation impl_factory = {
-+ PW_VERSION_FACTORY_IMPLEMENTATION,
-+ .create_object = create_object,
-+};
-+
-+static void module_destroy(void *data)
-+{
-+ struct factory_data *d = data;
-+
-+ spa_hook_remove(&d->module_listener);
-+
-+ if (d->properties)
-+ pw_properties_free(d->properties);
-+
-+ pw_factory_destroy(d->this);
-+}
-+
-+static const struct pw_module_events module_events = {
-+ PW_VERSION_MODULE_EVENTS,
-+ .destroy = module_destroy,
-+};
-+
-+static int module_init(struct pw_module *module, struct pw_properties *properties)
-+{
-+ struct pw_core *core = pw_module_get_core(module);
-+ struct pw_factory *factory;
-+ struct factory_data *data;
-+
-+ factory = pw_factory_new(core,
-+ "client-endpoint",
-+ PW_TYPE_INTERFACE_ClientEndpoint,
-+ PW_VERSION_CLIENT_ENDPOINT,
-+ NULL,
-+ sizeof(*data));
-+ if (factory == NULL)
-+ return -ENOMEM;
-+
-+ data = pw_factory_get_user_data(factory);
-+ data->this = factory;
-+ data->module = module;
-+ data->properties = properties;
-+
-+ pw_log_debug("module-endpoint %p: new", module);
-+
-+ pw_factory_set_implementation(factory, &impl_factory, data);
-+ pw_factory_register(factory, NULL, pw_module_get_global(module), NULL);
-+
-+ pw_protocol_native_ext_endpoint_init(core);
-+
-+ pw_module_add_listener(module, &data->module_listener, &module_events, data);
-+ pw_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
-+
-+ return 0;
-+}
-+
-+SPA_EXPORT
-+int pipewire__module_init(struct pw_module *module, const char *args)
-+{
-+ return module_init(module, NULL);
-+}
-diff --git a/src/modules/module-endpoint/endpoint-impl.c b/src/modules/module-endpoint/endpoint-impl.c
-new file mode 100644
-index 00000000..252eeca1
---- /dev/null
-+++ b/src/modules/module-endpoint/endpoint-impl.c
-@@ -0,0 +1,428 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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 "endpoint-impl.h"
-+#include <pipewire/private.h>
-+#include <spa/pod/filter.h>
-+#include <spa/pod/compare.h>
-+
-+struct pw_endpoint {
-+ struct pw_core *core;
-+ struct pw_global *global;
-+ struct pw_global *parent;
-+
-+ struct pw_client_endpoint *client_ep;
-+
-+ uint32_t n_params;
-+ struct spa_pod **params;
-+
-+ struct pw_endpoint_info info;
-+ struct pw_properties *props;
-+};
-+
-+struct pw_client_endpoint {
-+ struct pw_resource *owner_resource;
-+ struct spa_hook owner_resource_listener;
-+
-+ struct pw_endpoint endpoint;
-+};
-+
-+struct resource_data {
-+ struct pw_endpoint *endpoint;
-+ struct pw_client_endpoint *client_ep;
-+
-+ struct spa_hook resource_listener;
-+
-+ uint32_t n_subscribe_ids;
-+ uint32_t subscribe_ids[32];
-+};
-+
-+static int
-+endpoint_enum_params (void *object, int seq,
-+ uint32_t id, uint32_t start, uint32_t num,
-+ const struct spa_pod *filter)
-+{
-+ struct pw_resource *resource = object;
-+ struct resource_data *data = pw_resource_get_user_data(resource);
-+ struct pw_endpoint *this = data->endpoint;
-+ struct spa_pod *result;
-+ struct spa_pod *param;
-+ uint8_t buffer[1024];
-+ struct spa_pod_builder b = { 0 };
-+ uint32_t index;
-+ uint32_t next = start;
-+ uint32_t count = 0;
-+
-+ while (true) {
-+ index = next++;
-+ if (index >= this->n_params)
-+ break;
-+
-+ param = this->params[index];
-+
-+ if (param == NULL || !spa_pod_is_object_id(param, id))
-+ continue;
-+
-+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
-+ if (spa_pod_filter(&b, &result, param, filter) != 0)
-+ continue;
-+
-+ pw_log_debug("endpoint %p: %d param %u", this, seq, index);
-+
-+ pw_endpoint_resource_param(resource, seq, id, index, next, result);
-+
-+ if (++count == num)
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int
-+endpoint_subscribe_params (void *object, uint32_t *ids, uint32_t n_ids)
-+{
-+ struct pw_resource *resource = object;
-+ struct resource_data *data = pw_resource_get_user_data(resource);
-+ uint32_t i;
-+
-+ n_ids = SPA_MIN(n_ids, SPA_N_ELEMENTS(data->subscribe_ids));
-+ data->n_subscribe_ids = n_ids;
-+
-+ for (i = 0; i < n_ids; i++) {
-+ data->subscribe_ids[i] = ids[i];
-+ pw_log_debug("endpoint %p: resource %d subscribe param %u",
-+ data->endpoint, resource->id, ids[i]);
-+ endpoint_enum_params(resource, 1, ids[i], 0, UINT32_MAX, NULL);
-+ }
-+ return 0;
-+}
-+
-+static int
-+endpoint_set_param (void *object, uint32_t id, uint32_t flags,
-+ const struct spa_pod *param)
-+{
-+ struct pw_resource *resource = object;
-+ struct resource_data *data = pw_resource_get_user_data(resource);
-+ struct pw_client_endpoint *client_ep = data->client_ep;
-+
-+ pw_client_endpoint_resource_set_param(client_ep->owner_resource,
-+ id, flags, param);
-+
-+ return 0;
-+}
-+
-+static const struct pw_endpoint_proxy_methods endpoint_methods = {
-+ PW_VERSION_ENDPOINT_PROXY_METHODS,
-+ .subscribe_params = endpoint_subscribe_params,
-+ .enum_params = endpoint_enum_params,
-+ .set_param = endpoint_set_param,
-+};
-+
-+static void
-+endpoint_unbind(void *data)
-+{
-+ struct pw_resource *resource = data;
-+ spa_list_remove(&resource->link);
-+}
-+
-+static const struct pw_resource_events resource_events = {
-+ PW_VERSION_RESOURCE_EVENTS,
-+ .destroy = endpoint_unbind,
-+};
-+
-+static int
-+endpoint_bind(void *_data, struct pw_client *client, uint32_t permissions,
-+ uint32_t version, uint32_t id)
-+{
-+ struct pw_endpoint *this = _data;
-+ struct pw_global *global = this->global;
-+ struct pw_resource *resource;
-+ struct resource_data *data;
-+
-+ resource = pw_resource_new(client, id, permissions, global->type, version, sizeof(*data));
-+ if (resource == NULL)
-+ goto no_mem;
-+
-+ data = pw_resource_get_user_data(resource);
-+ data->endpoint = this;
-+ data->client_ep = this->client_ep;
-+ pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource);
-+
-+ pw_resource_set_implementation(resource, &endpoint_methods, resource);
-+
-+ pw_log_debug("endpoint %p: bound to %d", this, resource->id);
-+
-+ spa_list_append(&global->resource_list, &resource->link);
-+
-+ this->info.change_mask = PW_ENDPOINT_CHANGE_MASK_PARAMS |
-+ PW_ENDPOINT_CHANGE_MASK_PROPS;
-+ pw_endpoint_resource_info(resource, &this->info);
-+ this->info.change_mask = 0;
-+
-+ return 0;
-+
-+ no_mem:
-+ pw_log_error("can't create node resource");
-+ return -ENOMEM;
-+}
-+
-+static int
-+pw_endpoint_init(struct pw_endpoint *this,
-+ struct pw_core *core,
-+ struct pw_client *owner,
-+ struct pw_global *parent,
-+ struct pw_properties *properties)
-+{
-+ struct pw_properties *props = NULL;
-+
-+ pw_log_debug("endpoint %p: new", this);
-+
-+ this->core = core;
-+ this->parent = parent;
-+
-+ props = properties ? properties : pw_properties_new(NULL, NULL);
-+ if (!props)
-+ goto no_mem;
-+
-+ this->props = pw_properties_copy (props);
-+ if (!this->props)
-+ goto no_mem;
-+
-+ this->global = pw_global_new (core,
-+ PW_TYPE_INTERFACE_Endpoint,
-+ PW_VERSION_ENDPOINT,
-+ props, endpoint_bind, this);
-+ if (!this->global)
-+ goto no_mem;
-+
-+ this->info.id = this->global->id;
-+ this->info.props = &this->props->dict;
-+
-+ return pw_global_register(this->global, owner, parent);
-+
-+ no_mem:
-+ pw_log_error("can't create endpoint - out of memory");
-+ if (props && !properties)
-+ pw_properties_free(props);
-+ if (this->props)
-+ pw_properties_free(this->props);
-+ return -ENOMEM;
-+}
-+
-+static void
-+pw_endpoint_clear(struct pw_endpoint *this)
-+{
-+ uint32_t i;
-+
-+ pw_log_debug("endpoint %p: destroy", this);
-+
-+ pw_global_destroy(this->global);
-+
-+ for (i = 0; i < this->n_params; i++)
-+ free(this->params[i]);
-+ free(this->params);
-+
-+ free(this->info.params);
-+
-+ if (this->props)
-+ pw_properties_free(this->props);
-+}
-+
-+static void
-+endpoint_notify_subscribed(struct pw_endpoint *this,
-+ uint32_t index, uint32_t next)
-+{
-+ struct pw_global *global = this->global;
-+ struct pw_resource *resource;
-+ struct resource_data *data;
-+ struct spa_pod *param = this->params[index];
-+ uint32_t id;
-+ uint32_t i;
-+
-+ if (!param || !spa_pod_is_object (param))
-+ return;
-+
-+ id = SPA_POD_OBJECT_ID (param);
-+
-+ spa_list_for_each(resource, &global->resource_list, link) {
-+ data = pw_resource_get_user_data(resource);
-+ for (i = 0; i < data->n_subscribe_ids; i++) {
-+ if (data->subscribe_ids[i] == id) {
-+ pw_endpoint_resource_param(resource, 1, id,
-+ index, next, param);
-+ }
-+ }
-+ }
-+}
-+
-+static int
-+client_endpoint_update(void *object,
-+ uint32_t change_mask,
-+ uint32_t n_params,
-+ const struct spa_pod **params,
-+ const struct pw_endpoint_info *info)
-+{
-+ struct pw_client_endpoint *cliep = object;
-+ struct pw_endpoint *this = &cliep->endpoint;
-+
-+ if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS) {
-+ uint32_t i;
-+
-+ pw_log_debug("endpoint %p: update %d params", this, n_params);
-+
-+ for (i = 0; i < this->n_params; i++)
-+ free(this->params[i]);
-+ this->n_params = n_params;
-+ this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *));
-+
-+ for (i = 0; i < this->n_params; i++) {
-+ this->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
-+ endpoint_notify_subscribed(this, i, i+1);
-+ }
-+ }
-+ else if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_PARAMS_INCREMENTAL) {
-+ uint32_t i, j;
-+ const struct spa_pod_prop *pold, *pnew;
-+
-+ pw_log_debug("endpoint %p: update %d params incremental", this, n_params);
-+
-+ for (i = 0; i < this->n_params; i++) {
-+ /* we only support incremental updates for controls */
-+ if (!spa_pod_is_object_id (this->params[i], PW_ENDPOINT_PARAM_Control))
-+ continue;
-+
-+ for (j = 0; j < n_params; j++) {
-+ if (!spa_pod_is_object_id (params[j], PW_ENDPOINT_PARAM_Control)) {
-+ pw_log_warn ("endpoint %p: ignoring incremental update "
-+ "on non-control param", this);
-+ continue;
-+ }
-+
-+ pold = spa_pod_object_find_prop (
-+ (const struct spa_pod_object *) this->params[i],
-+ NULL, PW_ENDPOINT_PARAM_CONTROL_id);
-+ pnew = spa_pod_object_find_prop (
-+ (const struct spa_pod_object *) params[j],
-+ NULL, PW_ENDPOINT_PARAM_CONTROL_id);
-+
-+ if (pold && pnew && spa_pod_compare (&pold->value, &pnew->value) == 0) {
-+ free (this->params[i]);
-+ this->params[i] = spa_pod_copy (params[j]);
-+ endpoint_notify_subscribed(this, i, UINT32_MAX);
-+ }
-+ }
-+ }
-+ }
-+
-+ if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_INFO) {
-+ struct pw_global *global = this->global;
-+ struct pw_resource *resource;
-+
-+ if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
-+ size_t size = info->n_params * sizeof(struct spa_param_info);
-+ free(this->info.params);
-+ this->info.params = malloc(size);
-+ this->info.n_params = info->n_params;
-+ memcpy(this->info.params, info->params, size);
-+ }
-+
-+ if (info->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
-+ pw_properties_update(this->props, info->props);
-+ }
-+
-+ this->info.change_mask = info->change_mask;
-+ spa_list_for_each(resource, &global->resource_list, link) {
-+ pw_endpoint_resource_info(resource, &this->info);
-+ }
-+ this->info.change_mask = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct pw_client_endpoint_proxy_methods client_endpoint_methods = {
-+ PW_VERSION_CLIENT_ENDPOINT_PROXY_METHODS,
-+ .update = client_endpoint_update,
-+};
-+
-+static void
-+client_endpoint_resource_destroy(void *data)
-+{
-+ struct pw_client_endpoint *this = data;
-+
-+ pw_log_debug("client-endpoint %p: destroy", this);
-+
-+ pw_endpoint_clear(&this->endpoint);
-+
-+ this->owner_resource = NULL;
-+ spa_hook_remove(&this->owner_resource_listener);
-+ free(this);
-+}
-+
-+static const struct pw_resource_events owner_resource_events = {
-+ PW_VERSION_RESOURCE_EVENTS,
-+ .destroy = client_endpoint_resource_destroy,
-+};
-+
-+struct pw_client_endpoint *
-+pw_client_endpoint_new(struct pw_resource *owner_resource,
-+ struct pw_global *parent,
-+ struct pw_properties *properties)
-+{
-+ struct pw_client_endpoint *this;
-+ struct pw_client *owner = pw_resource_get_client(owner_resource);
-+ struct pw_core *core = pw_client_get_core(owner);
-+
-+ this = calloc(1, sizeof(struct pw_client_endpoint));
-+ if (this == NULL)
-+ return NULL;
-+
-+ pw_log_debug("client-endpoint %p: new", this);
-+
-+ if (pw_endpoint_init(&this->endpoint, core, owner, parent, properties) < 0)
-+ goto error_no_endpoint;
-+ this->endpoint.client_ep = this;
-+
-+ this->owner_resource = owner_resource;
-+ pw_resource_add_listener(this->owner_resource,
-+ &this->owner_resource_listener,
-+ &owner_resource_events,
-+ this);
-+ pw_resource_set_implementation(this->owner_resource,
-+ &client_endpoint_methods,
-+ this);
-+
-+ return this;
-+
-+ error_no_endpoint:
-+ pw_resource_destroy(owner_resource);
-+ free(this);
-+ return NULL;
-+}
-+
-+void
-+pw_client_endpoint_destroy(struct pw_client_endpoint *this)
-+{
-+ pw_resource_destroy(this->owner_resource);
-+}
-diff --git a/src/modules/module-endpoint/endpoint-impl.h b/src/modules/module-endpoint/endpoint-impl.h
-new file mode 100644
-index 00000000..059aa904
---- /dev/null
-+++ b/src/modules/module-endpoint/endpoint-impl.h
-@@ -0,0 +1,52 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef PIPEWIRE_ENDPOINT_IMPL_H
-+#define PIPEWIRE_ENDPOINT_IMPL_H
-+
-+#include <pipewire/pipewire.h>
-+#include <extensions/endpoint.h>
-+#include <extensions/client-endpoint.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+struct pw_endpoint;
-+struct pw_client_endpoint;
-+
-+struct pw_client_endpoint *
-+pw_client_endpoint_new(struct pw_resource *resource,
-+ struct pw_global *parent,
-+ struct pw_properties *properties);
-+
-+void
-+pw_client_endpoint_destroy(struct pw_client_endpoint *endpoint);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* PIPEWIRE_ENDPOINT_IMPL_H */
-diff --git a/src/modules/module-endpoint/protocol-native.c b/src/modules/module-endpoint/protocol-native.c
-new file mode 100644
-index 00000000..a41d3119
---- /dev/null
-+++ b/src/modules/module-endpoint/protocol-native.c
-@@ -0,0 +1,472 @@
-+/* PipeWire
-+ *
-+ * Copyright © 2019 Collabora Ltd.
-+ * @author George Kiagiadakis <george.kiagiadakis@collabora.com>
-+ *
-+ * 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 <pipewire/pipewire.h>
-+#include <spa/pod/parser.h>
-+
-+#include <extensions/client-endpoint.h>
-+#include <extensions/endpoint.h>
-+#include <extensions/protocol-native.h>
-+
-+static void
-+serialize_pw_endpoint_info(struct spa_pod_builder *b,
-+ const struct pw_endpoint_info *info)
-+{
-+ struct spa_pod_frame f;
-+ uint32_t i, n_props;
-+
-+ n_props = info->props ? info->props->n_items : 0;
-+
-+ spa_pod_builder_push_struct(b, &f);
-+ spa_pod_builder_add(b,
-+ SPA_POD_Id(info->id),
-+ SPA_POD_Int(info->change_mask),
-+ SPA_POD_Int(info->n_params),
-+ SPA_POD_Int(n_props),
-+ NULL);
-+
-+ for (i = 0; i < info->n_params; i++) {
-+ spa_pod_builder_add(b,
-+ SPA_POD_Id(info->params[i].id),
-+ SPA_POD_Int(info->params[i].flags), NULL);
-+ }
-+
-+ for (i = 0; i < n_props; i++) {
-+ spa_pod_builder_add(b,
-+ SPA_POD_String(info->props->items[i].key),
-+ SPA_POD_String(info->props->items[i].value),
-+ NULL);
-+ }
-+
-+ spa_pod_builder_pop(b, &f);
-+}
-+
-+/* macro because of alloca() */
-+#define deserialize_pw_endpoint_info(p, f, info) \
-+do { \
-+ if (spa_pod_parser_push_struct(p, f) < 0 || \
-+ spa_pod_parser_get(p, \
-+ SPA_POD_Id(&(info)->id), \
-+ SPA_POD_Int(&(info)->change_mask), \
-+ SPA_POD_Int(&(info)->n_params), \
-+ SPA_POD_Int(&(info)->props->n_items), \
-+ NULL) < 0) \
-+ return -EINVAL; \
-+ \
-+ if ((info)->n_params > 0) \
-+ (info)->params = alloca((info)->n_params * sizeof(struct spa_param_info)); \
-+ if ((info)->props->n_items > 0) \
-+ (info)->props->items = alloca((info)->props->n_items * sizeof(struct spa_dict_item)); \
-+ \
-+ for (i = 0; i < (info)->n_params; i++) { \
-+ if (spa_pod_parser_get(p, \
-+ SPA_POD_Id(&(info)->params[i].id), \
-+ SPA_POD_Int(&(info)->params[i].flags), \
-+ NULL) < 0) \
-+ return -EINVAL; \
-+ } \
-+ \
-+ for (i = 0; i < (info)->props->n_items; i++) { \
-+ if (spa_pod_parser_get(p, \
-+ SPA_POD_String(&(info)->props->items[i].key), \
-+ SPA_POD_String(&(info)->props->items[i].value), \
-+ NULL) < 0) \
-+ return -EINVAL; \
-+ } \
-+ \
-+ spa_pod_parser_pop(p, f); \
-+} while(0)
-+
-+static int
-+endpoint_marshal_subscribe_params(void *object, uint32_t *ids, uint32_t n_ids)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_proxy(proxy,
-+ PW_ENDPOINT_PROXY_METHOD_SUBSCRIBE_PARAMS, NULL);
-+
-+ spa_pod_builder_add_struct(b,
-+ SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, n_ids, ids));
-+
-+ return pw_protocol_native_end_proxy(proxy, b);
-+}
-+
-+static int
-+endpoint_demarshal_subscribe_params(void *object, const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_parser prs;
-+ uint32_t csize, ctype, n_ids;
-+ uint32_t *ids;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_get_struct(&prs,
-+ SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0)
-+ return -EINVAL;
-+
-+ if (ctype != SPA_TYPE_Id)
-+ return -EINVAL;
-+
-+ return pw_resource_do(resource, struct pw_endpoint_proxy_methods,
-+ subscribe_params, 0, ids, n_ids);
-+}
-+
-+static int
-+endpoint_marshal_enum_params(void *object, int seq, uint32_t id,
-+ uint32_t index, uint32_t num, const struct spa_pod *filter)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_proxy(proxy,
-+ PW_ENDPOINT_PROXY_METHOD_ENUM_PARAMS, NULL);
-+
-+ spa_pod_builder_add_struct(b,
-+ SPA_POD_Int(seq),
-+ SPA_POD_Id(id),
-+ SPA_POD_Int(index),
-+ SPA_POD_Int(num),
-+ SPA_POD_Pod(filter));
-+
-+ return pw_protocol_native_end_proxy(proxy, b);
-+}
-+
-+static int
-+endpoint_demarshal_enum_params(void *object, const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_parser prs;
-+ uint32_t id, index, num;
-+ int seq;
-+ struct spa_pod *filter;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_get_struct(&prs,
-+ SPA_POD_Int(&seq),
-+ SPA_POD_Id(&id),
-+ SPA_POD_Int(&index),
-+ SPA_POD_Int(&num),
-+ SPA_POD_Pod(&filter)) < 0)
-+ return -EINVAL;
-+
-+ return pw_resource_do(resource, struct pw_endpoint_proxy_methods,
-+ enum_params, 0, seq, id, index, num, filter);
-+}
-+
-+static int
-+endpoint_marshal_set_param(void *object, uint32_t id, uint32_t flags,
-+ const struct spa_pod *param)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_proxy(proxy,
-+ PW_ENDPOINT_PROXY_METHOD_SET_PARAM, NULL);
-+
-+ spa_pod_builder_add_struct(b,
-+ SPA_POD_Id(id),
-+ SPA_POD_Int(flags),
-+ SPA_POD_Pod(param));
-+ return pw_protocol_native_end_proxy(proxy, b);
-+}
-+
-+static int
-+endpoint_demarshal_set_param(void *object, const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_parser prs;
-+ uint32_t id, flags;
-+ struct spa_pod *param;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_get_struct(&prs,
-+ SPA_POD_Id(&id),
-+ SPA_POD_Int(&flags),
-+ SPA_POD_Pod(&param)) < 0)
-+ return -EINVAL;
-+
-+ return pw_resource_do(resource, struct pw_endpoint_proxy_methods,
-+ set_param, 0, id, flags, param);
-+}
-+
-+static void
-+endpoint_marshal_info(void *object, const struct pw_endpoint_info *info)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_resource(resource,
-+ PW_ENDPOINT_PROXY_EVENT_INFO, NULL);
-+ serialize_pw_endpoint_info (b, info);
-+ pw_protocol_native_end_resource(resource, b);
-+}
-+
-+static int
-+endpoint_demarshal_info(void *object, const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_parser prs;
-+ struct spa_pod_frame f;
-+ struct spa_dict props = SPA_DICT_INIT(NULL, 0);
-+ struct pw_endpoint_info info = { .props = &props };
-+ uint32_t i;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+
-+ deserialize_pw_endpoint_info(&prs, &f, &info);
-+
-+ return pw_proxy_notify(proxy, struct pw_endpoint_proxy_events,
-+ info, 0, &info);
-+}
-+
-+static void
-+endpoint_marshal_param(void *object, int seq, uint32_t id,
-+ uint32_t index, uint32_t next, const struct spa_pod *param)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_resource(resource,
-+ PW_ENDPOINT_PROXY_EVENT_PARAM, NULL);
-+
-+ spa_pod_builder_add_struct(b,
-+ SPA_POD_Int(seq),
-+ SPA_POD_Id(id),
-+ SPA_POD_Int(index),
-+ SPA_POD_Int(next),
-+ SPA_POD_Pod(param));
-+
-+ pw_protocol_native_end_resource(resource, b);
-+}
-+
-+static int
-+endpoint_demarshal_param(void *object, const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_parser prs;
-+ uint32_t id, index, next;
-+ int seq;
-+ struct spa_pod *param;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_get_struct(&prs,
-+ SPA_POD_Int(&seq),
-+ SPA_POD_Id(&id),
-+ SPA_POD_Int(&index),
-+ SPA_POD_Int(&next),
-+ SPA_POD_Pod(&param)) < 0)
-+ return -EINVAL;
-+
-+ return pw_proxy_notify(proxy, struct pw_endpoint_proxy_events, param, 0,
-+ seq, id, index, next, param);
-+}
-+
-+static const struct pw_endpoint_proxy_methods pw_protocol_native_endpoint_method_marshal = {
-+ PW_VERSION_ENDPOINT_PROXY_METHODS,
-+ &endpoint_marshal_subscribe_params,
-+ &endpoint_marshal_enum_params,
-+ &endpoint_marshal_set_param,
-+};
-+
-+static const struct pw_protocol_native_demarshal pw_protocol_native_endpoint_method_demarshal[] = {
-+ { &endpoint_demarshal_subscribe_params, 0 },
-+ { &endpoint_demarshal_enum_params, 0 },
-+ { &endpoint_demarshal_set_param, 0 }
-+};
-+
-+static const struct pw_endpoint_proxy_events pw_protocol_native_endpoint_event_marshal = {
-+ PW_VERSION_ENDPOINT_PROXY_EVENTS,
-+ &endpoint_marshal_info,
-+ &endpoint_marshal_param,
-+};
-+
-+static const struct pw_protocol_native_demarshal pw_protocol_native_endpoint_event_demarshal[] = {
-+ { &endpoint_demarshal_info, 0 },
-+ { &endpoint_demarshal_param, 0 }
-+};
-+
-+static const struct pw_protocol_marshal pw_protocol_native_endpoint_marshal = {
-+ PW_TYPE_INTERFACE_Endpoint,
-+ PW_VERSION_ENDPOINT,
-+ PW_ENDPOINT_PROXY_METHOD_NUM,
-+ PW_ENDPOINT_PROXY_EVENT_NUM,
-+ &pw_protocol_native_endpoint_method_marshal,
-+ &pw_protocol_native_endpoint_method_demarshal,
-+ &pw_protocol_native_endpoint_event_marshal,
-+ &pw_protocol_native_endpoint_event_demarshal,
-+};
-+
-+
-+static int
-+client_endpoint_marshal_update(
-+ void *object,
-+ uint32_t change_mask,
-+ uint32_t n_params,
-+ const struct spa_pod **params,
-+ const struct pw_endpoint_info *info)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_builder *b;
-+ struct spa_pod_frame f;
-+ uint32_t i;
-+
-+ b = pw_protocol_native_begin_proxy(proxy,
-+ PW_CLIENT_ENDPOINT_PROXY_METHOD_UPDATE, NULL);
-+
-+ spa_pod_builder_push_struct(b, &f);
-+ spa_pod_builder_add(b,
-+ SPA_POD_Int(change_mask),
-+ SPA_POD_Int(n_params), NULL);
-+
-+ for (i = 0; i < n_params; i++)
-+ spa_pod_builder_add(b, SPA_POD_Pod(params[i]), NULL);
-+
-+ if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_INFO)
-+ serialize_pw_endpoint_info(b, info);
-+
-+ spa_pod_builder_pop(b, &f);
-+
-+ return pw_protocol_native_end_proxy(proxy, b);
-+}
-+
-+static int
-+client_endpoint_demarshal_update(void *object,
-+ const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_parser prs;
-+ struct spa_pod_frame f[2];
-+ uint32_t change_mask, n_params;
-+ const struct spa_pod **params = NULL;
-+ struct spa_dict props = SPA_DICT_INIT(NULL, 0);
-+ struct pw_endpoint_info info = { .props = &props };
-+ uint32_t i;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_push_struct(&prs, &f[0]) < 0 ||
-+ spa_pod_parser_get(&prs,
-+ SPA_POD_Int(&change_mask),
-+ SPA_POD_Int(&n_params), NULL) < 0)
-+ return -EINVAL;
-+
-+ if (n_params > 0)
-+ params = alloca(n_params * sizeof(struct spa_pod *));
-+ for (i = 0; i < n_params; i++)
-+ if (spa_pod_parser_get(&prs,
-+ SPA_POD_PodObject(&params[i]), NULL) < 0)
-+ return -EINVAL;
-+
-+ if (change_mask & PW_CLIENT_ENDPOINT_UPDATE_INFO)
-+ deserialize_pw_endpoint_info(&prs, &f[1], &info);
-+
-+ pw_resource_do(resource, struct pw_client_endpoint_proxy_methods,
-+ update, 0, change_mask, n_params, params, &info);
-+ return 0;
-+}
-+
-+static void
-+client_endpoint_marshal_set_param (void *object,
-+ uint32_t id, uint32_t flags,
-+ const struct spa_pod *param)
-+{
-+ struct pw_resource *resource = object;
-+ struct spa_pod_builder *b;
-+
-+ b = pw_protocol_native_begin_resource(resource,
-+ PW_CLIENT_ENDPOINT_PROXY_EVENT_SET_PARAM, NULL);
-+
-+ spa_pod_builder_add_struct(b,
-+ SPA_POD_Id(id),
-+ SPA_POD_Int(flags),
-+ SPA_POD_Pod(param));
-+
-+ pw_protocol_native_end_resource(resource, b);
-+}
-+
-+static int
-+client_endpoint_demarshal_set_param(void *object,
-+ const struct pw_protocol_native_message *msg)
-+{
-+ struct pw_proxy *proxy = object;
-+ struct spa_pod_parser prs;
-+ uint32_t id, flags;
-+ const struct spa_pod *param = NULL;
-+
-+ spa_pod_parser_init(&prs, msg->data, msg->size);
-+ if (spa_pod_parser_get_struct(&prs,
-+ SPA_POD_Id(&id),
-+ SPA_POD_Int(&flags),
-+ SPA_POD_PodObject(&param)) < 0)
-+ return -EINVAL;
-+
-+ pw_proxy_notify(proxy, struct pw_client_endpoint_proxy_events,
-+ set_param, 0, id, flags, param);
-+ return 0;
-+}
-+
-+static const struct pw_client_endpoint_proxy_methods pw_protocol_native_client_endpoint_method_marshal = {
-+ PW_VERSION_CLIENT_ENDPOINT_PROXY_METHODS,
-+ &client_endpoint_marshal_update,
-+};
-+
-+static const struct pw_protocol_native_demarshal pw_protocol_native_client_endpoint_method_demarshal[] = {
-+ { &client_endpoint_demarshal_update, 0 }
-+};
-+
-+static const struct pw_client_endpoint_proxy_events pw_protocol_native_client_endpoint_event_marshal = {
-+ PW_VERSION_CLIENT_ENDPOINT_PROXY_EVENTS,
-+ &client_endpoint_marshal_set_param,
-+};
-+
-+static const struct pw_protocol_native_demarshal pw_protocol_native_client_endpoint_event_demarshal[] = {
-+ { &client_endpoint_demarshal_set_param, 0 }
-+};
-+
-+static const struct pw_protocol_marshal pw_protocol_native_client_endpoint_marshal = {
-+ PW_TYPE_INTERFACE_ClientEndpoint,
-+ PW_VERSION_CLIENT_ENDPOINT,
-+ PW_CLIENT_ENDPOINT_PROXY_METHOD_NUM,
-+ PW_CLIENT_ENDPOINT_PROXY_EVENT_NUM,
-+ &pw_protocol_native_client_endpoint_method_marshal,
-+ &pw_protocol_native_client_endpoint_method_demarshal,
-+ &pw_protocol_native_client_endpoint_event_marshal,
-+ &pw_protocol_native_client_endpoint_event_demarshal,
-+};
-+
-+struct pw_protocol *pw_protocol_native_ext_endpoint_init(struct pw_core *core)
-+{
-+ struct pw_protocol *protocol;
-+
-+ protocol = pw_core_find_protocol(core, PW_TYPE_INFO_PROTOCOL_Native);
-+
-+ if (protocol == NULL)
-+ return NULL;
-+
-+ pw_protocol_add_marshal(protocol, &pw_protocol_native_client_endpoint_marshal);
-+ pw_protocol_add_marshal(protocol, &pw_protocol_native_endpoint_marshal);
-+
-+ return protocol;
-+}
-diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c
-index a8752438..bbbf9420 100644
---- a/src/pipewire/pipewire.c
-+++ b/src/pipewire/pipewire.c
-@@ -647,6 +647,8 @@ static const struct spa_type_info type_info[] = {
- { PW_TYPE_INTERFACE_Module, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Module", NULL },
- { PW_TYPE_INTERFACE_ClientNode, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "ClientNode", NULL },
- { PW_TYPE_INTERFACE_Device, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Device", NULL },
-+ { PW_TYPE_INTERFACE_Endpoint, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "Endpoint", NULL},
-+ { PW_TYPE_INTERFACE_ClientEndpoint, SPA_TYPE_Pointer, PW_TYPE_INFO_INTERFACE_BASE "ClientEndpoint", NULL},
- { SPA_ID_INVALID, SPA_ID_INVALID, "spa_types", spa_types },
- { 0, 0, NULL, NULL },
- };
-diff --git a/src/pipewire/type.h b/src/pipewire/type.h
-index a1b205f7..39544913 100644
---- a/src/pipewire/type.h
-+++ b/src/pipewire/type.h
-@@ -48,7 +48,8 @@ enum {
- /* extensions */
- PW_TYPE_INTERFACE_EXTENSIONS = PW_TYPE_INTERFACE_START + 0x1000,
- PW_TYPE_INTERFACE_ClientNode,
--
-+ PW_TYPE_INTERFACE_Endpoint,
-+ PW_TYPE_INTERFACE_ClientEndpoint,
- };
-
- #define PW_TYPE_INFO_BASE "PipeWire:"
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0010-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch
index 6b1a6441..b3eba21f 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0010-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch
@@ -1,4 +1,4 @@
-From bbc875ec4268a88bf2465244e089b119011e7479 Mon Sep 17 00:00:00 2001
+From 1b1f884a165ed7b2147affbdddf85a641d4cf180 Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Tue, 19 Feb 2019 18:23:19 +0200
Subject: [PATCH] gst: Implement new pwaudio{src,sink} elements, based on
@@ -14,17 +14,18 @@ These are much more reliable elements to use for audio data.
Both elements share a common ringbuffer that actually implements
the pipewire integration.
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/140]
+Upstream-Status: Denied
+See https://gitlab.freedesktop.org/pipewire/pipewire/merge_requests/140
---
src/gst/gstpipewire.c | 8 +-
- src/gst/gstpwaudioringbuffer.c | 542 +++++++++++++++++++++++++++++++++
+ src/gst/gstpwaudioringbuffer.c | 565 +++++++++++++++++++++++++++++++++
src/gst/gstpwaudioringbuffer.h | 83 +++++
- src/gst/gstpwaudiosink.c | 200 ++++++++++++
+ src/gst/gstpwaudiosink.c | 207 ++++++++++++
src/gst/gstpwaudiosink.h | 48 +++
src/gst/gstpwaudiosrc.c | 200 ++++++++++++
src/gst/gstpwaudiosrc.h | 48 +++
src/gst/meson.build | 6 +
- 8 files changed, 1134 insertions(+), 1 deletion(-)
+ 8 files changed, 1164 insertions(+), 1 deletion(-)
create mode 100644 src/gst/gstpwaudioringbuffer.c
create mode 100644 src/gst/gstpwaudioringbuffer.h
create mode 100644 src/gst/gstpwaudiosink.c
@@ -65,10 +66,10 @@ index 4040264b..68fd446f 100644
}
diff --git a/src/gst/gstpwaudioringbuffer.c b/src/gst/gstpwaudioringbuffer.c
new file mode 100644
-index 00000000..989b2cd7
+index 00000000..babf2d83
--- /dev/null
+++ b/src/gst/gstpwaudioringbuffer.c
-@@ -0,0 +1,542 @@
+@@ -0,0 +1,565 @@
+/* PipeWire
+ *
+ * Copyright © 2018 Wim Taymans
@@ -273,24 +274,41 @@ index 00000000..989b2cd7
+ enum pw_stream_state state, const char *error)
+{
+ GstPwAudioRingBuffer *self = GST_PW_AUDIO_RING_BUFFER (data);
++ GstMessage *msg;
+
+ GST_DEBUG_OBJECT (self->elem, "got stream state: %s",
+ pw_stream_state_as_string (state));
+
+ switch (state) {
++ case PW_STREAM_STATE_ERROR:
++ GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
++ ("stream error: %s", error), (NULL));
++ break;
+ case PW_STREAM_STATE_UNCONNECTED:
+ GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
+ ("stream disconnected unexpectedly"), (NULL));
+ break;
+ case PW_STREAM_STATE_CONNECTING:
-+ case PW_STREAM_STATE_CONFIGURE:
-+ case PW_STREAM_STATE_READY:
++ break;
+ case PW_STREAM_STATE_PAUSED:
-+ case PW_STREAM_STATE_STREAMING:
++ if (old == PW_STREAM_STATE_STREAMING) {
++ if (GST_STATE (self->elem) != GST_STATE_PAUSED &&
++ GST_STATE_TARGET (self->elem) != GST_STATE_PAUSED) {
++ GST_DEBUG_OBJECT (self->elem, "requesting GST_STATE_PAUSED");
++ msg = gst_message_new_request_state (GST_OBJECT (self->elem),
++ GST_STATE_PAUSED);
++ gst_element_post_message (self->elem, msg);
++ }
++ }
+ break;
-+ case PW_STREAM_STATE_ERROR:
-+ GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
-+ ("stream error: %s", error), (NULL));
++ case PW_STREAM_STATE_STREAMING:
++ if (GST_STATE (self->elem) != GST_STATE_PLAYING &&
++ GST_STATE_TARGET (self->elem) != GST_STATE_PLAYING) {
++ GST_DEBUG_OBJECT (self->elem, "requesting GST_STATE_PLAYING");
++ msg = gst_message_new_request_state (GST_OBJECT (self->elem),
++ GST_STATE_PLAYING);
++ gst_element_post_message (self->elem, msg);
++ }
+ break;
+ }
+ pw_thread_loop_signal (self->main_loop, FALSE);
@@ -311,13 +329,16 @@ index 00000000..989b2cd7
+}
+
+static void
-+on_stream_format_changed (void *data, const struct spa_pod *format)
++on_stream_param_changed (void *data, uint32_t id, const struct spa_pod *format)
+{
+ GstPwAudioRingBuffer *self = GST_PW_AUDIO_RING_BUFFER (data);
+ const struct spa_pod *params[1];
+ struct spa_pod_builder b = { NULL };
+ uint8_t buffer[512];
+
++ if (format == NULL || id != SPA_PARAM_Format)
++ return;
++
+ spa_pod_builder_init (&b, buffer, sizeof (buffer));
+ params[0] = spa_pod_builder_add_object (&b,
+ SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
@@ -328,7 +349,7 @@ index 00000000..989b2cd7
+ SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
+
+ GST_DEBUG_OBJECT (self->elem, "doing finish format, buffer size:%d", self->segsize);
-+ pw_stream_finish_format (self->stream, 0, params, 1);
++ pw_stream_update_params (self->stream, params, 1);
+}
+
+static void
@@ -353,7 +374,7 @@ index 00000000..989b2cd7
+
+ b = pw_stream_dequeue_buffer (self->stream);
+ if (!b) {
-+ GST_WARNING_OBJECT (self->elem, "no pipewire buffer available");
++ GST_INFO_OBJECT (self->elem, "no pipewire buffer available");
+ return;
+ }
+
@@ -417,7 +438,7 @@ index 00000000..989b2cd7
+static const struct pw_stream_events stream_events = {
+ PW_VERSION_STREAM_EVENTS,
+ .state_changed = on_stream_state_changed,
-+ .format_changed = on_stream_format_changed,
++ .param_changed = on_stream_param_changed,
+ .process = on_stream_process,
+};
+
@@ -454,11 +475,9 @@ index 00000000..989b2cd7
+
+ /* construct param & props objects */
+
++ props = pw_properties_new (NULL, NULL);
+ if (self->props->properties) {
-+ props = pw_properties_new (NULL, NULL);
+ gst_structure_foreach (self->props->properties, copy_properties, props);
-+ } else {
-+ props = NULL;
+ }
+
+ spa_pod_builder_init (&b, buffer, sizeof (buffer));
@@ -475,6 +494,11 @@ index 00000000..989b2cd7
+ self->rate = GST_AUDIO_INFO_RATE (&spec->info);
+ self->segoffset = 0;
+
++ pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%u",
++ self->segsize / self->bpf, self->rate);
++ GST_DEBUG_OBJECT (self->elem, "segsize:%u, bpf:%u, node.latency = %s",
++ self->segsize, self->bpf, pw_properties_get (props, PW_KEY_NODE_LATENCY));
++
+ /* connect stream */
+
+ pw_thread_loop_lock (self->main_loop);
@@ -494,9 +518,9 @@ index 00000000..989b2cd7
+ params, 1) < 0)
+ goto start_error;
+
-+ GST_DEBUG_OBJECT (self->elem, "waiting for stream READY");
++ GST_DEBUG_OBJECT (self->elem, "waiting for stream CONFIGURE");
+
-+ if (!wait_for_stream_state (self, PW_STREAM_STATE_READY))
++ if (!wait_for_stream_state (self, PW_STREAM_STATE_PAUSED))
+ goto start_error;
+
+ pw_thread_loop_unlock (self->main_loop);
@@ -702,10 +726,10 @@ index 00000000..f47f668a
+#endif
diff --git a/src/gst/gstpwaudiosink.c b/src/gst/gstpwaudiosink.c
new file mode 100644
-index 00000000..6cb71385
+index 00000000..069996c3
--- /dev/null
+++ b/src/gst/gstpwaudiosink.c
-@@ -0,0 +1,200 @@
+@@ -0,0 +1,207 @@
+/* PipeWire
+ *
+ * Copyright © 2018 Wim Taymans
@@ -765,6 +789,13 @@ index 00000000..6cb71385
+gst_pw_audio_sink_init (GstPwAudioSink * self)
+{
+ self->props.fd = -1;
++
++ /* Bump the default buffer size up to 21.3 ms, which is the default on most
++ * sound cards, in hope to match the alsa buffer size on the pipewire server.
++ * This may not always happen, but it still sounds better than the 10ms
++ * default latency. This is temporary until we have a better mechanism to
++ * select the appropriate latency */
++ GST_AUDIO_BASE_SINK (self)->latency_time = 21333;
+}
+
+static void
@@ -1245,5 +1276,5 @@ index ad0e0801..0e922347 100644
pipewire_gst_c_args = [
--
-2.20.1
+2.24.0
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-pipewire-cli-add-support-for-printing-endpoint-info-.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-pipewire-cli-add-support-for-printing-endpoint-info-.patch
deleted file mode 100644
index a709abdf..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0003-pipewire-cli-add-support-for-printing-endpoint-info-.patch
+++ /dev/null
@@ -1,149 +0,0 @@
-From 0e9fe3cfb19c751655f16ce4b8c6100269f23ff2 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Tue, 28 May 2019 11:46:36 +0300
-Subject: [PATCH] pipewire-cli: add support for printing endpoint info & params
-
-Note that you have to run:
- load-module libpipewire-module-endpoint
-before trying to query any endpoints
-
-Upstream-Status: Pending
----
- src/tools/pipewire-cli.c | 78 +++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 77 insertions(+), 1 deletion(-)
-
-diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c
-index 521739f6..9511db82 100644
---- a/src/tools/pipewire-cli.c
-+++ b/src/tools/pipewire-cli.c
-@@ -38,6 +38,8 @@
- #include <pipewire/type.h>
- #include <pipewire/permission.h>
-
-+#include <extensions/endpoint.h>
-+
- static const char WHITESPACE[] = " \t";
-
- struct remote_data;
-@@ -176,8 +178,12 @@ static void print_params(struct spa_param_info *params, uint32_t n_params, char
- return;
- }
- for (i = 0; i < n_params; i++) {
-+ const struct spa_type_info *type_info = spa_type_param;
-+ if (params[i].id >= PW_ENDPOINT_PARAM_EnumControl)
-+ type_info = endpoint_param_type_info;
-+
- fprintf(stdout, "%c\t %d (%s) %c%c\n", mark, params[i].id,
-- spa_debug_type_find_name(spa_type_param, params[i].id),
-+ spa_debug_type_find_name(type_info, params[i].id),
- params[i].flags & SPA_PARAM_INFO_READ ? 'r' : '-',
- params[i].flags & SPA_PARAM_INFO_WRITE ? 'w' : '-');
- }
-@@ -641,6 +647,16 @@ static void info_device(struct proxy_data *pd)
- info->change_mask = 0;
- }
-
-+static void info_endpoint(struct proxy_data *pd)
-+{
-+ struct pw_endpoint_info *info = pd->info;
-+
-+ info_global(pd);
-+ print_properties(info->props, MARK_CHANGE(1), true);
-+ print_params(info->params, info->n_params, MARK_CHANGE(0), true);
-+ info->change_mask = 0;
-+}
-+
- static void core_event_info(void *object, const struct pw_core_info *info)
- {
- struct proxy_data *pd = object;
-@@ -708,6 +724,9 @@ static void event_param(void *object, int seq, uint32_t id,
-
- if (spa_pod_is_object_type(param, SPA_TYPE_OBJECT_Format))
- spa_debug_format(2, NULL, param);
-+ else if (spa_pod_is_object_type(param, PW_ENDPOINT_OBJECT_ParamControl) ||
-+ spa_pod_is_object_type(param, PW_ENDPOINT_OBJECT_ParamStream))
-+ spa_debug_pod(2, endpoint_param_object_type_info, param);
- else
- spa_debug_pod(2, NULL, param);
- }
-@@ -842,6 +861,53 @@ static const struct pw_device_proxy_events device_events = {
- .param = event_param
- };
-
-+static void endpoint_info_free(struct pw_endpoint_info *info)
-+{
-+ free(info->params);
-+ if (info->props)
-+ pw_properties_free ((struct pw_properties *)info->props);
-+ free(info);
-+}
-+
-+static void endpoint_event_info(void *object,
-+ const struct pw_endpoint_info *update)
-+{
-+ struct proxy_data *pd = object;
-+ struct remote_data *rd = pd->rd;
-+ struct pw_endpoint_info *info = pd->info;
-+
-+ if (!info) {
-+ info = pd->info = calloc(1, sizeof(*info));
-+ info->id = update->id;
-+ }
-+ if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PARAMS) {
-+ info->n_params = update->n_params;
-+ free(info->params);
-+ info->params = malloc(info->n_params * sizeof(struct spa_param_info));
-+ memcpy(info->params, update->params,
-+ info->n_params * sizeof(struct spa_param_info));
-+ }
-+ if (update->change_mask & PW_ENDPOINT_CHANGE_MASK_PROPS) {
-+ if (info->props)
-+ pw_properties_free ((struct pw_properties *)info->props);
-+ info->props =
-+ (struct spa_dict *) pw_properties_new_dict (update->props);
-+ }
-+
-+ if (pd->global == NULL)
-+ pd->global = pw_map_lookup(&rd->globals, info->id);
-+ if (pd->global && pd->global->info_pending) {
-+ info_endpoint(pd);
-+ pd->global->info_pending = false;
-+ }
-+}
-+
-+static const struct pw_endpoint_proxy_events endpoint_events = {
-+ PW_VERSION_ENDPOINT_PROXY_EVENTS,
-+ .info = endpoint_event_info,
-+ .param = event_param
-+};
-+
- static void
- destroy_proxy (void *data)
- {
-@@ -928,6 +994,12 @@ static bool bind_global(struct remote_data *rd, struct global *global, char **er
- destroy = (pw_destroy_t) pw_link_info_free;
- info_func = info_link;
- break;
-+ case PW_TYPE_INTERFACE_Endpoint:
-+ events = &endpoint_events;
-+ client_version = PW_VERSION_ENDPOINT;
-+ destroy = (pw_destroy_t) endpoint_info_free;
-+ info_func = info_endpoint;
-+ break;
- default:
- asprintf(error, "unsupported type %s", spa_debug_type_find_name(pw_type_info(), global->type));
- return false;
-@@ -1201,6 +1273,10 @@ static bool do_enum_params(struct data *data, const char *cmd, char *args, char
- pw_device_proxy_enum_params((struct pw_device_proxy*)global->proxy, 0,
- param_id, 0, 0, NULL);
- break;
-+ case PW_TYPE_INTERFACE_Endpoint:
-+ pw_endpoint_proxy_enum_params((struct pw_endpoint_proxy*)global->proxy, 0,
-+ param_id, 0, 0, NULL);
-+ break;
- default:
- asprintf(error, "enum-params not implemented on object %d", atoi(a[0]));
- return false;
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-audioconvert-always-assume-that-output-ports-are-NOT.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-audioconvert-always-assume-that-output-ports-are-NOT.patch
new file mode 100644
index 00000000..beb87839
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-audioconvert-always-assume-that-output-ports-are-NOT.patch
@@ -0,0 +1,35 @@
+From ce155eb0073fba84556782633f79bb7d03492c07 Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Wed, 2 Oct 2019 21:40:34 +0300
+Subject: [PATCH] audioconvert: always assume that output ports are NOT monitor
+ ports
+
+Otherwise, when we setup audioconvert in merge+split mode,
+it assumes that the splitter's ports are monitor ports and
+belong to the merger.
+
+Upstream-Status: Inappropriate [workaround]
+---
+ spa/plugins/audioconvert/audioconvert.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c
+index 74a62a35..72da37d1 100644
+--- a/spa/plugins/audioconvert/audioconvert.c
++++ b/spa/plugins/audioconvert/audioconvert.c
+@@ -113,8 +113,12 @@ struct impl {
+ unsigned int add_listener:1;
+ };
+
++#if 0
+ #define IS_MONITOR_PORT(this,dir,port_id) (dir == SPA_DIRECTION_OUTPUT && port_id > 0 && \
+ this->mode[SPA_DIRECTION_INPUT] == SPA_PARAM_PORT_CONFIG_MODE_dsp)
++#else
++#define IS_MONITOR_PORT(this,dir,port_id) (false)
++#endif
+
+ static void emit_node_info(struct impl *this, bool full)
+ {
+--
+2.24.0
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-pipewire-cli-add-command-to-modify-endpoint-control-.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-pipewire-cli-add-command-to-modify-endpoint-control-.patch
deleted file mode 100644
index 4394d60d..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0004-pipewire-cli-add-command-to-modify-endpoint-control-.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 824c8abf88e9ee82567c177145798b619298ab91 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Wed, 5 Jun 2019 14:57:37 +0300
-Subject: [PATCH] pipewire-cli: add command to modify endpoint control values
-
-Upstream-Status: Pending
----
- src/tools/pipewire-cli.c | 86 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 86 insertions(+)
-
-diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c
-index 9511db82..b52ab100 100644
---- a/src/tools/pipewire-cli.c
-+++ b/src/tools/pipewire-cli.c
-@@ -210,6 +210,7 @@ static bool do_export_node(struct data *data, const char *cmd, char *args, char
- static bool do_enum_params(struct data *data, const char *cmd, char *args, char **error);
- static bool do_permissions(struct data *data, const char *cmd, char *args, char **error);
- static bool do_get_permissions(struct data *data, const char *cmd, char *args, char **error);
-+static bool do_endpoint_control(struct data *data, const char *cmd, char *args, char **error);
-
- static struct command command_list[] = {
- { "help", "Show this help", do_help },
-@@ -228,6 +229,7 @@ static struct command command_list[] = {
- { "enum-params", "Enumerate params of an object <object-id> [<param-id-name>]", do_enum_params },
- { "permissions", "Set permissions for a client <client-id> <permissions>", do_permissions },
- { "get-permissions", "Get permissions of a client <client-id>", do_get_permissions },
-+ { "endpoint-control", "Set control value on an endpoint <object-id> <control-id> <type: b|i|l|d> <value>", do_endpoint_control },
- };
-
- static bool do_help(struct data *data, const char *cmd, char *args, char **error)
-@@ -1357,6 +1359,90 @@ static bool do_get_permissions(struct data *data, const char *cmd, char *args, c
- return true;
- }
-
-+static bool do_endpoint_control(struct data *data, const char *cmd, char *args, char **error)
-+{
-+ struct remote_data *rd = data->current;
-+ int n;
-+ char *a[4];
-+ uint32_t id, control_id;
-+ struct global *global;
-+ char buffer[1024];
-+ struct spa_pod_builder b;
-+ struct spa_pod_frame f;
-+ struct spa_pod *param;
-+
-+ n = pw_split_ip(args, WHITESPACE, 4, a);
-+ if (n < 4) {
-+ asprintf(error, "%s <object-id> <control-id> <type: b|i|l|d> <value>", cmd);
-+ return false;
-+ }
-+
-+ id = atoi(a[0]);
-+ global = pw_map_lookup(&rd->globals, id);
-+ if (global == NULL) {
-+ asprintf(error, "%s: unknown global %d", cmd, id);
-+ return false;
-+ }
-+ if (global->type != PW_TYPE_INTERFACE_Endpoint) {
-+ asprintf(error, "object %d is not an endpoint", atoi(a[0]));
-+ return false;
-+ }
-+ if (global->proxy == NULL) {
-+ if (!bind_global(rd, global, error))
-+ return false;
-+ }
-+
-+ control_id = atoi(a[1]);
-+
-+ spa_pod_builder_init(&b, buffer, 1024);
-+ spa_pod_builder_push_object (&b, &f,
-+ PW_ENDPOINT_OBJECT_ParamControl, PW_ENDPOINT_PARAM_Control);
-+ spa_pod_builder_add(&b,
-+ PW_ENDPOINT_PARAM_CONTROL_id, SPA_POD_Int(control_id),
-+ NULL);
-+
-+ switch (*a[2]) {
-+ case 'b': {
-+ bool val = atoi(a[3]);
-+ spa_pod_builder_add(&b,
-+ PW_ENDPOINT_PARAM_CONTROL_value, SPA_POD_Bool(val),
-+ NULL);
-+ break;
-+ }
-+ case 'i': {
-+ int val = atoi(a[3]);
-+ spa_pod_builder_add(&b,
-+ PW_ENDPOINT_PARAM_CONTROL_value, SPA_POD_Int(val),
-+ NULL);
-+ break;
-+ }
-+ case 'l': {
-+ int64_t val = strtoll(a[3], NULL, 10);
-+ spa_pod_builder_add(&b,
-+ PW_ENDPOINT_PARAM_CONTROL_value, SPA_POD_Long(val),
-+ NULL);
-+ break;
-+ }
-+ case 'd': {
-+ double val = strtod(a[3], NULL);
-+ spa_pod_builder_add(&b,
-+ PW_ENDPOINT_PARAM_CONTROL_value, SPA_POD_Double(val),
-+ NULL);
-+ break;
-+ }
-+ default:
-+ asprintf(error, "%s: unknown value type %s", cmd, a[2]);
-+ return false;
-+ }
-+
-+ param = spa_pod_builder_pop(&b, &f);
-+
-+ pw_endpoint_proxy_set_param((struct pw_endpoint_proxy *) global->proxy,
-+ PW_ENDPOINT_PARAM_Control, 0, param);
-+
-+ return true;
-+}
-+
- static bool parse(struct data *data, char *buf, size_t size, char **error)
- {
- char *a[2];
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-module-access-add-same-sec-label-mode.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-module-access-add-same-sec-label-mode.patch
new file mode 100644
index 00000000..07a1ec11
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0005-module-access-add-same-sec-label-mode.patch
@@ -0,0 +1,94 @@
+From 19fad1a4fa8bdc4f02aac4e169e7ff9cab18bdcd Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Tue, 19 Nov 2019 17:09:07 +0200
+Subject: [PATCH] module-access: add same-sec-label-mode
+
+This is a mode where the access module allows all clients that have
+the same security label as the pipewire daemon, and every other
+client is put on the restricted state.
+
+In systems that use SMACK security labels, such as AGL, this allows
+the session manager (which is spawned by pipewire, inheriting the
+same smack label) to have full access to all objects, while every
+other client is restricted and the session manager must decide
+what to do with it
+
+Note that while this option is configurable, there is no loss of
+security if this option is not set in the configuration. Clients
+that don't have the same security context will be considered to
+be flatpak clients because pipewire will not be able to open
+/proc/pid/cmdline. This however results in some unwanted error
+messages that may be confusing.
+
+Upstream-Status: Inappropriate [agl/smack specific]
+---
+ src/modules/module-access.c | 45 ++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 44 insertions(+), 1 deletion(-)
+
+diff --git a/src/modules/module-access.c b/src/modules/module-access.c
+index 09dafa43..f75306d9 100644
+--- a/src/modules/module-access.c
++++ b/src/modules/module-access.c
+@@ -50,6 +50,30 @@ struct impl {
+ struct spa_hook module_listener;
+ };
+
++static int check_seclabel(const char *str)
++{
++ char attr[1024];
++ int fd, len;
++
++ fd = open("/proc/self/attr/current", O_RDONLY);
++ if (fd < 0)
++ return -errno;
++
++ if ((len = read(fd, attr, 1024)) <= 0) {
++ close(fd);
++ return -EIO;
++ }
++ attr[len] = '\0';
++
++ if (strcmp(attr, str) == 0) {
++ close(fd);
++ return 1;
++ }
++
++ close(fd);
++ return 0;
++}
++
+ static int check_cmdline(struct pw_client *client, int pid, const char *str)
+ {
+ char path[2048];
+@@ -121,8 +145,27 @@ core_check_access(void *data, struct pw_client *client)
+ const char *str;
+ int pid, res;
+
++ props = pw_client_get_properties(client);
++
++ if (impl->properties &&
++ (str = pw_properties_get(impl->properties, "same-sec-label-mode")) != NULL &&
++ strcmp(str, "1") == 0) {
++ if (props && (str = pw_properties_get(props, PW_KEY_SEC_LABEL)) != NULL) {
++ res = check_seclabel(str);
++ if (res == 1)
++ goto granted;
++ else if (res < 0)
++ pw_log_warn("module %p: client %p seclabel check failed: %s",
++ impl, client, spa_strerror(res));
++ }
++ pw_log_debug("module %p: seclabel restricted client %p added",
++ impl, client);
++ items[0] = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, "restricted");
++ goto wait_permissions;
++ }
++
+ pid = -EINVAL;
+- if ((props = pw_client_get_properties(client)) != NULL) {
++ if (props != NULL) {
+ if ((str = pw_properties_get(props, PW_KEY_SEC_PID)) != NULL)
+ pid = atoi(str);
+ }
+--
+2.24.0
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-alsa-pcm-call-reuse_buffers-when-resetting-the-state.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-alsa-pcm-call-reuse_buffers-when-resetting-the-state.patch
new file mode 100644
index 00000000..cae4d70f
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-alsa-pcm-call-reuse_buffers-when-resetting-the-state.patch
@@ -0,0 +1,30 @@
+From 5946fbd2ca3a7f892b4ebc10090f62df6bb1ec88 Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Thu, 9 Jan 2020 19:27:23 +0200
+Subject: [PATCH] alsa-pcm: call reuse_buffers when resetting the state of the
+ buffers
+
+This allows the upstream node to put buffers back to its pool in case
+they were left around in the ready list locally when the alsa-pcm-sink
+was last paused.
+
+Fixes #203
+---
+ spa/plugins/alsa/alsa-pcm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c
+index 63d75549..a6f22cf0 100644
+--- a/spa/plugins/alsa/alsa-pcm.c
++++ b/spa/plugins/alsa/alsa-pcm.c
+@@ -1115,6 +1115,7 @@ static void reset_buffers(struct state *this)
+ struct buffer *b = &this->buffers[i];
+ if (this->stream == SND_PCM_STREAM_PLAYBACK) {
+ SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
++ spa_node_call_reuse_buffer(&this->callbacks, 0, b->id);
+ } else {
+ spa_list_append(&this->free, &b->link);
+ SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT);
+--
+2.24.1
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-logger-print-timestamps-on-logged-messages.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-logger-print-timestamps-on-logged-messages.patch
deleted file mode 100644
index 4d9117f0..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0006-logger-print-timestamps-on-logged-messages.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 352c58357e5922b21d664c1f5a0b89a74f864f41 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Wed, 3 Jul 2019 17:47:46 +0300
-Subject: [PATCH] logger: print timestamps on logged messages
-
-Timestamps have usec precision and the seconds are limited
-to 9 digits. Usually what matters in these messages is to spot
-delays between printouts and not really what is the absolute
-time of the system.
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/164]
----
- spa/plugins/support/logger.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/spa/plugins/support/logger.c b/spa/plugins/support/logger.c
-index 87ba3c21..2976601c 100644
---- a/spa/plugins/support/logger.c
-+++ b/spa/plugins/support/logger.c
-@@ -27,6 +27,7 @@
- #include <string.h>
- #include <errno.h>
- #include <stdio.h>
-+#include <time.h>
- #include <sys/eventfd.h>
-
- #include <spa/support/log.h>
-@@ -70,6 +71,9 @@ impl_log_logv(struct spa_log *log,
- const char *prefix = "", *suffix = "";
- int size;
- bool do_trace;
-+ struct timespec now;
-+
-+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
-
- if ((do_trace = (level == SPA_LOG_LEVEL_TRACE && impl->have_source)))
- level++;
-@@ -86,8 +90,9 @@ impl_log_logv(struct spa_log *log,
- }
-
- vsnprintf(text, sizeof(text), fmt, args);
-- size = snprintf(location, sizeof(location), "%s[%s][%s:%i %s()] %s%s\n",
-- prefix, levels[level], strrchr(file, '/') + 1, line, func, text, suffix);
-+ size = snprintf(location, sizeof(location), "%s[%s][%09lu.%06lu][%s:%i %s()] %s%s\n",
-+ prefix, levels[level], now.tv_sec & 0x1FFFFFFF, now.tv_nsec / 1000,
-+ strrchr(file, '/') + 1, line, func, text, suffix);
-
- if (SPA_UNLIKELY(do_trace)) {
- uint32_t index;
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0007-alsa-make-corrections-on-the-timeout-based-on-how-fa.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0007-alsa-make-corrections-on-the-timeout-based-on-how-fa.patch
deleted file mode 100644
index 86495014..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0007-alsa-make-corrections-on-the-timeout-based-on-how-fa.patch
+++ /dev/null
@@ -1,130 +0,0 @@
-From 05a3a926df4906cdf60f7978843c637bbf37714a Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Tue, 9 Jul 2019 18:06:18 +0300
-Subject: [PATCH] alsa: make corrections on the timeout based on how fast ALSA
- consumes samples
-
-This feels a bit hacky, but it actually makes huge difference when pipewire is
-running in qemu.
-
-The idea is that it keeps track of how much samples are in the device
-(fill level) and calculates how many are consumed when a timeout occurs.
-Then it converts that into a time based on the sample rate and compares it to
-the system clock time that elapsed since the last write to the device.
-The division between the two gives a rate (drift) that can be used to shorten
-the timeout window.
-
-So for instance, if the timeout window was 21.3 ms, but the device actually
-consumed an equivalent of 28 ms in samples, the drift will be 21.3/28 = 0.76
-and the next timeout window will be approximately 21.3 * 0.76 = 16.1 ms
-
-To avoid making things worse, the drift is clamped between 0.6 and 1.0.
-Min 0.6 was arbitrarily chosen, but sometimes alsa does report strange numbers,
-causing the drift to be very low, which in turn causes an early wakeup.
-Max 1.0 basically means that we don't care if the device is consuming samples
-slower. In that case, the early wakeup mechanism will throttle pipewire.
-
-Fixes #163
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/166]
----
- spa/plugins/alsa/alsa-utils.c | 31 ++++++++++++++++++++++++++-----
- spa/plugins/alsa/alsa-utils.h | 2 ++
- 2 files changed, 28 insertions(+), 5 deletions(-)
-
-diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c
-index 87582c1c..872969bf 100644
---- a/spa/plugins/alsa/alsa-utils.c
-+++ b/spa/plugins/alsa/alsa-utils.c
-@@ -593,7 +593,21 @@ static int get_status(struct state *state, snd_pcm_sframes_t *delay)
-
- static int update_time(struct state *state, uint64_t nsec, snd_pcm_sframes_t delay, bool slave)
- {
-- double err, corr;
-+ double err, corr, drift;
-+ snd_pcm_sframes_t consumed;
-+
-+ consumed = state->fill_level - delay;
-+ if (state->alsa_started && consumed > 0) {
-+ double sysclk_diff = nsec - state->last_time;
-+ double devclk_diff = ((double) consumed) * 1e9 / state->rate;
-+ drift = sysclk_diff / devclk_diff;
-+ drift = SPA_CLAMP(drift, 0.6, 1.0);
-+
-+ spa_log_trace_fp(state->log, "cons:%ld sclk:%f dclk:%f drift:%f",
-+ consumed, sysclk_diff, devclk_diff, drift);
-+ } else {
-+ drift = 1.0;
-+ }
-
- if (state->stream == SND_PCM_STREAM_PLAYBACK)
- err = delay - state->last_threshold;
-@@ -650,11 +664,11 @@ static int update_time(struct state *state, uint64_t nsec, snd_pcm_sframes_t del
- state->clock->rate_diff = corr;
- }
-
-- spa_log_trace_fp(state->log, "slave:%d %"PRIu64" %f %ld %f %f %d", slave, nsec,
-- corr, delay, err, state->threshold * corr,
-+ spa_log_trace_fp(state->log, "slave:%d %"PRIu64" %f %ld %f %f %f %d", slave, nsec,
-+ corr, delay, err, state->threshold * corr, drift,
- state->threshold);
-
-- state->next_time += state->threshold / corr * 1e9 / state->rate;
-+ state->next_time += state->threshold / corr * drift * 1e9 / state->rate;
- state->last_threshold = state->threshold;
-
- return 0;
-@@ -783,6 +797,10 @@ again:
- goto again;
-
- state->sample_count += total_written;
-+ state->fill_level += total_written;
-+
-+ clock_gettime(CLOCK_MONOTONIC, &state->now);
-+ state->last_time = SPA_TIMESPEC_TO_NSEC (&state->now);
-
- if (!state->alsa_started && total_written > 0) {
- spa_log_trace(state->log, "snd_pcm_start %lu", written);
-@@ -935,7 +953,7 @@ static int handle_play(struct state *state, uint64_t nsec, snd_pcm_sframes_t del
- {
- int res;
-
-- if (delay >= state->last_threshold * 2) {
-+ if (delay > state->last_threshold * 2) {
- spa_log_trace(state->log, "early wakeup %ld %d", delay, state->threshold);
- state->next_time = nsec + (delay - state->last_threshold) * SPA_NSEC_PER_SEC / state->rate;
- return -EAGAIN;
-@@ -944,6 +962,8 @@ static int handle_play(struct state *state, uint64_t nsec, snd_pcm_sframes_t del
- if ((res = update_time(state, nsec, delay, false)) < 0)
- return res;
-
-+ state->fill_level = delay;
-+
- if (spa_list_is_empty(&state->ready)) {
- struct spa_io_buffers *io = state->io;
-
-@@ -1072,6 +1092,7 @@ int spa_alsa_start(struct state *state)
-
- state->slaved = is_slaved(state);
- state->last_threshold = state->threshold;
-+ state->fill_level = 0;
-
- init_loop(state);
- state->safety = 0.0;
-diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h
-index a862873f..b53890b5 100644
---- a/spa/plugins/alsa/alsa-utils.h
-+++ b/spa/plugins/alsa/alsa-utils.h
-@@ -134,7 +134,9 @@ struct state {
- int64_t sample_time;
- uint64_t next_time;
- uint64_t base_time;
-+ uint64_t last_time;
-
-+ snd_pcm_uframes_t fill_level;
- uint64_t underrun;
- double safety;
-
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0008-audio-dsp-allow-mode-to-be-set-with-a-property.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0008-audio-dsp-allow-mode-to-be-set-with-a-property.patch
deleted file mode 100644
index 681bae69..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0008-audio-dsp-allow-mode-to-be-set-with-a-property.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 0c85e1110e32720785f861c7a85cf0636394eee4 Mon Sep 17 00:00:00 2001
-From: Julian Bouzas <julian.bouzas@collabora.com>
-Date: Thu, 27 Jun 2019 12:44:39 -0400
-Subject: [PATCH] audio-dsp: allow mode to be set with a property
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/167]
----
- src/modules/module-audio-dsp/audio-dsp.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/modules/module-audio-dsp/audio-dsp.c b/src/modules/module-audio-dsp/audio-dsp.c
-index be8a7592..68249307 100644
---- a/src/modules/module-audio-dsp/audio-dsp.c
-+++ b/src/modules/module-audio-dsp/audio-dsp.c
-@@ -264,7 +264,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
- {
- struct pw_node *node;
- struct node *n;
-- const char *api, *alias, *str, *factory;
-+ const char *api, *alias, *str, *factory, *mode;
- char node_name[128];
- struct pw_properties *pr;
- int i;
-@@ -279,6 +279,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
- pw_log_error("missing audio-dsp.name property");
- goto error;
- }
-+ mode = pw_properties_get(pr, "audio-dsp.mode");
-
- snprintf(node_name, sizeof(node_name), "system_%s", alias);
- for (i = 0; node_name[i]; i++) {
-@@ -296,7 +297,9 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
- if ((str = pw_properties_get(pr, "node.id")) != NULL)
- pw_properties_set(pr, "node.session", str);
-
-- if (direction == PW_DIRECTION_OUTPUT) {
-+ if (mode) {
-+ factory = mode;
-+ } else if (direction == PW_DIRECTION_OUTPUT) {
- pw_properties_set(pr, "merger.monitor", "1");
- factory = "merge";
- } else {
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0009-audioconvert-do-setup-internal-links-and-buffers-als.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0009-audioconvert-do-setup-internal-links-and-buffers-als.patch
deleted file mode 100644
index 87141e91..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0009-audioconvert-do-setup-internal-links-and-buffers-als.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From ddcda9fa6ec49168c5ddd9fbeda748c5fad18fce Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Wed, 10 Jul 2019 14:53:15 +0300
-Subject: [PATCH] audioconvert: do setup internal links and buffers also in
- convert mode
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/167]
----
- spa/plugins/audioconvert/audioconvert.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c
-index fa8dec97..0af0732d 100644
---- a/spa/plugins/audioconvert/audioconvert.c
-+++ b/spa/plugins/audioconvert/audioconvert.c
-@@ -79,6 +79,8 @@ struct impl {
- #define MODE_MERGE 1
- #define MODE_CONVERT 2
- int mode;
-+ bool fmt_is_set[2];
-+ bool buffers_set[2];
- bool started;
-
- struct spa_handle *hnd_fmt[2];
-@@ -791,11 +793,11 @@ impl_node_port_set_param(struct spa_node *node,
- if (id == SPA_PARAM_Format) {
- if (param == NULL)
- clean_convert(this);
-- else if ((direction == SPA_DIRECTION_OUTPUT && this->mode == MODE_MERGE) ||
-- (direction == SPA_DIRECTION_INPUT && this->mode == MODE_SPLIT)) {
-+ else if (this->fmt_is_set[SPA_DIRECTION_REVERSE(direction)]) {
- if ((res = setup_convert(this)) < 0)
- return res;
- }
-+ this->fmt_is_set[direction] = (param != NULL);
- }
- return res;
- }
-@@ -824,11 +826,11 @@ impl_node_port_use_buffers(struct spa_node *node,
- direction, port_id, buffers, n_buffers)) < 0)
- return res;
-
-- if ((direction == SPA_DIRECTION_OUTPUT && this->mode == MODE_MERGE) ||
-- (direction == SPA_DIRECTION_INPUT && this->mode == MODE_SPLIT)) {
-+ if (buffers && this->buffers_set[SPA_DIRECTION_REVERSE(direction)]) {
- if ((res = setup_buffers(this, SPA_DIRECTION_INPUT)) < 0)
- return res;
- }
-+ this->buffers_set[direction] = (buffers != NULL);
- return res;
- }
-
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0011-gst-pwaudioringbuffer-make-the-buffer-size-sensitive.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0011-gst-pwaudioringbuffer-make-the-buffer-size-sensitive.patch
deleted file mode 100644
index 5ffabb6d..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0011-gst-pwaudioringbuffer-make-the-buffer-size-sensitive.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 6e289d0058d71bc433d1918a8bbf3305f3e4f517 Mon Sep 17 00:00:00 2001
-From: Julian Bouzas <julian.bouzas@collabora.com>
-Date: Tue, 7 May 2019 10:36:35 -0400
-Subject: [PATCH] gst/pwaudioringbuffer: make the buffer size sensitive to the
- number of channels
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/140]
----
- src/gst/gstpwaudioringbuffer.c | 6 ++++--
- src/gst/gstpwaudioringbuffer.h | 1 +
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/gst/gstpwaudioringbuffer.c b/src/gst/gstpwaudioringbuffer.c
-index 989b2cd7..181304e8 100644
---- a/src/gst/gstpwaudioringbuffer.c
-+++ b/src/gst/gstpwaudioringbuffer.c
-@@ -246,17 +246,18 @@ on_stream_format_changed (void *data, const struct spa_pod *format)
- const struct spa_pod *params[1];
- struct spa_pod_builder b = { NULL };
- uint8_t buffer[512];
-+ const gint b_size = self->segsize * self->channels;
-
- spa_pod_builder_init (&b, buffer, sizeof (buffer));
- params[0] = spa_pod_builder_add_object (&b,
- SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
- SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(16, 1, INT32_MAX),
- SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
-- SPA_PARAM_BUFFERS_size, SPA_POD_Int(self->segsize),
-+ SPA_PARAM_BUFFERS_size, SPA_POD_Int(b_size),
- SPA_PARAM_BUFFERS_stride, SPA_POD_Int(self->bpf),
- SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
-
-- GST_DEBUG_OBJECT (self->elem, "doing finish format, buffer size:%d", self->segsize);
-+ GST_DEBUG_OBJECT (self->elem, "doing finish format, buffer size:%d", b_size);
- pw_stream_finish_format (self->stream, 0, params, 1);
- }
-
-@@ -402,6 +403,7 @@ gst_pw_audio_ring_buffer_acquire (GstAudioRingBuffer *buf,
- self->segsize = spec->segsize;
- self->bpf = GST_AUDIO_INFO_BPF (&spec->info);
- self->rate = GST_AUDIO_INFO_RATE (&spec->info);
-+ self->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
- self->segoffset = 0;
-
- /* connect stream */
-diff --git a/src/gst/gstpwaudioringbuffer.h b/src/gst/gstpwaudioringbuffer.h
-index f47f668a..f600f012 100644
---- a/src/gst/gstpwaudioringbuffer.h
-+++ b/src/gst/gstpwaudioringbuffer.h
-@@ -64,6 +64,7 @@ struct _GstPwAudioRingBuffer
- gint segsize;
- gint bpf;
- gint rate;
-+ gint channels;
-
- /* on_stream_process() state */
- gint segoffset;
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0012-gst-pwaudioringbuffer-request-pause-play-on-the-appr.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0012-gst-pwaudioringbuffer-request-pause-play-on-the-appr.patch
deleted file mode 100644
index 3680cc35..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0012-gst-pwaudioringbuffer-request-pause-play-on-the-appr.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 1eb1e3a839f97ad4aa43c289f702c587a068a333 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Thu, 11 Jul 2019 16:21:17 +0300
-Subject: [PATCH] gst/pwaudioringbuffer: request pause/play on the appropriate
- stream state changes
-
-This allows the client to properly go to PAUSED when the session manager
-unlinks the stream and go again to PLAYING when the sm re-links it.
-This allows the session manager to implement policies without letting
-the client pipeline freeze (in the absence of a running audio clock)
-when it is unlinked. Note that in case the client doesn't handle the
-request, there is still no issue. Like in pulseaudio, the clock just
-freezes, so the pipeline stops progressing.
-
-This is similar to the pulseaudio cork/uncork mechanism.
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/140]
----
- src/gst/gstpwaudioringbuffer.c | 27 +++++++++++++++++++++++----
- 1 file changed, 23 insertions(+), 4 deletions(-)
-
-diff --git a/src/gst/gstpwaudioringbuffer.c b/src/gst/gstpwaudioringbuffer.c
-index 181304e8..04259927 100644
---- a/src/gst/gstpwaudioringbuffer.c
-+++ b/src/gst/gstpwaudioringbuffer.c
-@@ -202,11 +202,16 @@ on_stream_state_changed (void *data, enum pw_stream_state old,
- enum pw_stream_state state, const char *error)
- {
- GstPwAudioRingBuffer *self = GST_PW_AUDIO_RING_BUFFER (data);
-+ GstMessage *msg;
-
- GST_DEBUG_OBJECT (self->elem, "got stream state: %s",
- pw_stream_state_as_string (state));
-
- switch (state) {
-+ case PW_STREAM_STATE_ERROR:
-+ GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
-+ ("stream error: %s", error), (NULL));
-+ break;
- case PW_STREAM_STATE_UNCONNECTED:
- GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
- ("stream disconnected unexpectedly"), (NULL));
-@@ -214,12 +219,26 @@ on_stream_state_changed (void *data, enum pw_stream_state old,
- case PW_STREAM_STATE_CONNECTING:
- case PW_STREAM_STATE_CONFIGURE:
- case PW_STREAM_STATE_READY:
-+ break;
- case PW_STREAM_STATE_PAUSED:
-- case PW_STREAM_STATE_STREAMING:
-+ if (old == PW_STREAM_STATE_STREAMING) {
-+ if (GST_STATE (self->elem) != GST_STATE_PAUSED &&
-+ GST_STATE_TARGET (self->elem) != GST_STATE_PAUSED) {
-+ GST_DEBUG_OBJECT (self->elem, "requesting GST_STATE_PAUSED");
-+ msg = gst_message_new_request_state (GST_OBJECT (self->elem),
-+ GST_STATE_PAUSED);
-+ gst_element_post_message (self->elem, msg);
-+ }
-+ }
- break;
-- case PW_STREAM_STATE_ERROR:
-- GST_ELEMENT_ERROR (self->elem, RESOURCE, FAILED,
-- ("stream error: %s", error), (NULL));
-+ case PW_STREAM_STATE_STREAMING:
-+ if (GST_STATE (self->elem) != GST_STATE_PLAYING &&
-+ GST_STATE_TARGET (self->elem) != GST_STATE_PLAYING) {
-+ GST_DEBUG_OBJECT (self->elem, "requesting GST_STATE_PLAYING");
-+ msg = gst_message_new_request_state (GST_OBJECT (self->elem),
-+ GST_STATE_PLAYING);
-+ gst_element_post_message (self->elem, msg);
-+ }
- break;
- }
- pw_thread_loop_signal (self->main_loop, FALSE);
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0013-gst-pwaudioringbuffer-wait-only-for-STREAM_STATE_CON.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0013-gst-pwaudioringbuffer-wait-only-for-STREAM_STATE_CON.patch
deleted file mode 100644
index 539e3a5e..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0013-gst-pwaudioringbuffer-wait-only-for-STREAM_STATE_CON.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 1b2bf0f435f2912c32fbd7a6118ed9bfb41f031c Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Thu, 11 Jul 2019 16:34:35 +0300
-Subject: [PATCH] gst/pwaudioringbuffer: wait only for STREAM_STATE_CONFIGURE
- when starting
-
-The CONFIGURE state is reached when the pw_client_node is exported,
-while the READY state requires the session manager to try and link
-the stream. If the SM does not want to link the stream due to policy,
-the client should not hang there forever.
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/140]
----
- src/gst/gstpwaudioringbuffer.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/gst/gstpwaudioringbuffer.c b/src/gst/gstpwaudioringbuffer.c
-index 04259927..b92b5feb 100644
---- a/src/gst/gstpwaudioringbuffer.c
-+++ b/src/gst/gstpwaudioringbuffer.c
-@@ -444,9 +444,9 @@ gst_pw_audio_ring_buffer_acquire (GstAudioRingBuffer *buf,
- params, 1) < 0)
- goto start_error;
-
-- GST_DEBUG_OBJECT (self->elem, "waiting for stream READY");
-+ GST_DEBUG_OBJECT (self->elem, "waiting for stream CONFIGURE");
-
-- if (!wait_for_stream_state (self, PW_STREAM_STATE_READY))
-+ if (!wait_for_stream_state (self, PW_STREAM_STATE_CONFIGURE))
- goto start_error;
-
- pw_thread_loop_unlock (self->main_loop);
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0014-gst-pwaudiosink-set-the-default-latency-time-buffer-.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0014-gst-pwaudiosink-set-the-default-latency-time-buffer-.patch
deleted file mode 100644
index 6f15b7f7..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0014-gst-pwaudiosink-set-the-default-latency-time-buffer-.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 460ce06c9cc6fd7b0106e0ce8a265bbeff4ae406 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Thu, 11 Jul 2019 17:07:15 +0300
-Subject: [PATCH] gst/pwaudiosink: set the default latency time (buffer size)
- to be 21.3ms
-
-This is to solve underrun issues that seem to appear with the default
-10ms latency that GstBaseAudioSink has.
-Hopefully in the future we will have a better mechanism to pick
-the appropriate latency instead of hardcoding it here.
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/140]
----
- src/gst/gstpwaudiosink.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/src/gst/gstpwaudiosink.c b/src/gst/gstpwaudiosink.c
-index 6cb71385..069996c3 100644
---- a/src/gst/gstpwaudiosink.c
-+++ b/src/gst/gstpwaudiosink.c
-@@ -57,6 +57,13 @@ static void
- gst_pw_audio_sink_init (GstPwAudioSink * self)
- {
- self->props.fd = -1;
-+
-+ /* Bump the default buffer size up to 21.3 ms, which is the default on most
-+ * sound cards, in hope to match the alsa buffer size on the pipewire server.
-+ * This may not always happen, but it still sounds better than the 10ms
-+ * default latency. This is temporary until we have a better mechanism to
-+ * select the appropriate latency */
-+ GST_AUDIO_BASE_SINK (self)->latency_time = 21333;
- }
-
- static void
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0015-audioconvert-fmtconvert-assume-F32-on-the-other-port.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0015-audioconvert-fmtconvert-assume-F32-on-the-other-port.patch
deleted file mode 100644
index ed3c1b06..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0015-audioconvert-fmtconvert-assume-F32-on-the-other-port.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From aa5de0cfc31df9cd8fb6d24367d2852dbbc8dcb9 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Mon, 29 Jul 2019 16:12:45 +0300
-Subject: [PATCH] audioconvert/fmtconvert: assume F32 on the other port when
- listing formats
-
-This allows picking F32LE as the default format on links that have
-no restriction and it avoids failing negotiation when the restricted
-end cannot handle S16/F32/F32P
-
-For instance this pipeline would previously fail:
-
- audio-dsp mode=merge ! audio-dsp mode=convert ! alsa-sink
-old negotiation: S16LE S24_32LE
-new negotiation: F32LE S24_32LE
-
-The link between the audio-dsp nodes has no restriction, so previously
-it would negotiate S16LE, which would then fail to negotiate with alsa-sink
-because fmtconvert does not know how to convert S16LE to S24_32LE directly.
-
-With this change, the middle link negotiates to F32LE, which can be
-converted to anything.
-
-Upstream-Status: Submitted [https://github.com/PipeWire/pipewire/pull/169]
----
- spa/plugins/audioconvert/fmtconvert.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/spa/plugins/audioconvert/fmtconvert.c b/spa/plugins/audioconvert/fmtconvert.c
-index df4ffb6b..a330f68f 100644
---- a/spa/plugins/audioconvert/fmtconvert.c
-+++ b/spa/plugins/audioconvert/fmtconvert.c
-@@ -338,7 +338,7 @@ static int port_enum_formats(struct spa_node *node,
- if (other->have_format)
- info = other->format;
- else
-- info.info.raw.format = SPA_AUDIO_FORMAT_S16;
-+ info.info.raw.format = SPA_AUDIO_FORMAT_F32;
-
- if (info.info.raw.format == SPA_AUDIO_FORMAT_F32P ||
- info.info.raw.format == SPA_AUDIO_FORMAT_F32) {
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0016-gst-pwaudioringbuffer-set-node.latency-to-get-schedu.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0016-gst-pwaudioringbuffer-set-node.latency-to-get-schedu.patch
deleted file mode 100644
index b97e21ff..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0016-gst-pwaudioringbuffer-set-node.latency-to-get-schedu.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 3af64cf4e1d33c33a9757c0f30c7de1068202540 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Tue, 20 Aug 2019 18:33:35 +0300
-Subject: [PATCH] gst: pwaudioringbuffer: set node.latency to get scheduled
- correctly in capture mode
-
-Upstream-Status: Pending
----
- src/gst/gstpwaudioringbuffer.c | 7 ++++---
- 1 file changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/src/gst/gstpwaudioringbuffer.c b/src/gst/gstpwaudioringbuffer.c
-index b92b5feb..2314dd77 100644
---- a/src/gst/gstpwaudioringbuffer.c
-+++ b/src/gst/gstpwaudioringbuffer.c
-@@ -403,11 +403,9 @@ gst_pw_audio_ring_buffer_acquire (GstAudioRingBuffer *buf,
-
- /* construct param & props objects */
-
-+ props = pw_properties_new (NULL, NULL);
- if (self->props->properties) {
-- props = pw_properties_new (NULL, NULL);
- gst_structure_foreach (self->props->properties, copy_properties, props);
-- } else {
-- props = NULL;
- }
-
- spa_pod_builder_init (&b, buffer, sizeof (buffer));
-@@ -425,6 +423,9 @@ gst_pw_audio_ring_buffer_acquire (GstAudioRingBuffer *buf,
- self->channels = GST_AUDIO_INFO_CHANNELS (&spec->info);
- self->segoffset = 0;
-
-+ pw_properties_setf(props, "node.latency", "%u/%u",
-+ self->segsize / self->bpf, self->rate);
-+
- /* connect stream */
-
- pw_thread_loop_lock (self->main_loop);
---
-2.23.0
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0017-connection-move-remaining-data-and-fds.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0017-connection-move-remaining-data-and-fds.patch
deleted file mode 100644
index be5ac5ea..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0017-connection-move-remaining-data-and-fds.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 75247f77eae2c473b18cf8d7e117216f73d2e127 Mon Sep 17 00:00:00 2001
-From: Wim Taymans <wtaymans@redhat.com>
-Date: Tue, 1 Oct 2019 10:43:48 +0200
-Subject: [PATCH] connection: move remaining data and fds
-
-If we can't send all of the data, move the remaining data to the
-start of the buffer so that we can send it again later.
-
-See #111
-
-Upstream-Status: Backport [3d48ba8394396fc8d8cadb1bff3514217ddd70e6]
----
- .../module-protocol-native/connection.c | 23 +++++++++++--------
- 1 file changed, 14 insertions(+), 9 deletions(-)
-
-diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c
-index dbb6a3cf..cb592e41 100644
---- a/src/modules/module-protocol-native/connection.c
-+++ b/src/modules/module-protocol-native/connection.c
-@@ -491,8 +491,12 @@ int pw_protocol_native_connection_flush(struct pw_protocol_native_connection *co
- if (sent < 0) {
- if (errno == EINTR)
- continue;
-- else
-- goto send_error;
-+ else {
-+ res = -errno;
-+ pw_log_error("could not sendmsg on fd:%d n_fds:%d: %s",
-+ conn->fd, n_fds, spa_strerror(res));
-+ goto exit;
-+ }
- }
- break;
- }
-@@ -504,15 +508,16 @@ int pw_protocol_native_connection_flush(struct pw_protocol_native_connection *co
- n_fds -= outfds;
- fds += outfds;
- }
-- buf->buffer_size = size;
-- buf->n_fds = n_fds;
-
-- return 0;
-+ res = 0;
-
-- /* ERRORS */
-- send_error:
-- res = -errno;
-- pw_log_error("could not sendmsg: %s", strerror(errno));
-+exit:
-+ if (size > 0)
-+ memmove(buf->buffer_data, data, size);
-+ buf->buffer_size = size;
-+ if (n_fds > 0)
-+ memmove(buf->fds, fds, n_fds * sizeof(int));
-+ buf->n_fds = n_fds;
- return res;
- }
-
---
-2.23.0
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0018-protocol-improve-flushing.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0018-protocol-improve-flushing.patch
deleted file mode 100644
index e027765e..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire/0018-protocol-improve-flushing.patch
+++ /dev/null
@@ -1,222 +0,0 @@
-From 7e885c029a6cc66ce1881f6f2c50d5f76a7d3372 Mon Sep 17 00:00:00 2001
-From: Wim Taymans <wtaymans@redhat.com>
-Date: Tue, 1 Oct 2019 12:53:56 +0200
-Subject: [PATCH] protocol: improve flushing
-
-Use the IO_OUT flag to schedule flushing instead of a flush_event.
-
-Handle EGAIN and wait for IO_OUT to try again.
-
-Fixes #111
-
-Upstream-Status: Backport [cc8e992cd155b4f19312a5036c7b744fc547410f]
----
- src/modules/module-protocol-native.c | 89 +++++++++++++------
- .../module-protocol-native/connection.c | 2 -
- 2 files changed, 62 insertions(+), 29 deletions(-)
-
-diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c
-index 411bad6c..b7cd3140 100644
---- a/src/modules/module-protocol-native.c
-+++ b/src/modules/module-protocol-native.c
-@@ -83,8 +83,7 @@ struct client {
- struct spa_hook conn_listener;
-
- bool disconnecting;
-- bool flush_signaled;
-- struct spa_source *flush_event;
-+ bool flushing;
- };
-
- struct server {
-@@ -106,6 +105,7 @@ struct client_data {
- struct spa_source *source;
- struct pw_protocol_native_connection *connection;
- bool busy;
-+ bool need_flush;
- };
-
- static void
-@@ -194,12 +194,14 @@ client_busy_changed(void *data, bool busy)
- {
- struct client_data *c = data;
- struct pw_client *client = c->client;
-- enum spa_io mask = SPA_IO_ERR | SPA_IO_HUP;
-+ uint32_t mask = c->source->mask;
-
- c->busy = busy;
-
-- if (!busy)
-- mask |= SPA_IO_IN;
-+ if (busy)
-+ SPA_FLAG_UNSET(mask, SPA_IO_IN);
-+ else
-+ SPA_FLAG_SET(mask, SPA_IO_IN);
-
- pw_log_debug("protocol-native %p: busy changed %d", client->protocol, busy);
- pw_loop_update_io(client->core->main_loop, c->source, mask);
-@@ -214,13 +216,32 @@ connection_data(void *data, int fd, enum spa_io mask)
- {
- struct client_data *this = data;
- struct pw_client *client = this->client;
-+ int res;
-
-- if (mask & (SPA_IO_ERR | SPA_IO_HUP)) {
-+ if (mask & SPA_IO_HUP) {
- pw_log_info("protocol-native %p: client %p disconnected", client->protocol, client);
- pw_client_destroy(client);
- return;
- }
--
-+ if (mask & SPA_IO_ERR) {
-+ pw_log_error("protocol-native %p: client %p error", client->protocol, client);
-+ pw_client_destroy(client);
-+ return;
-+ }
-+ if (mask & SPA_IO_OUT) {
-+ res = pw_protocol_native_connection_flush(this->connection);
-+ if (res >= 0) {
-+ int mask = this->source->mask;
-+ SPA_FLAG_UNSET(mask, SPA_IO_OUT);
-+ pw_loop_update_io(client->protocol->core->main_loop,
-+ this->source, mask);
-+ } else if (res != EAGAIN) {
-+ pw_log_error("client %p: could not flush: %s",
-+ client, spa_strerror(res));
-+ pw_client_destroy(client);
-+ return;
-+ }
-+ }
- if (mask & SPA_IO_IN)
- process_messages(this);
- }
-@@ -288,7 +309,8 @@ static struct pw_client *client_new(struct server *s, int fd)
-
- this->client = client;
- this->source = pw_loop_add_io(pw_core_get_main_loop(core),
-- fd, SPA_IO_ERR | SPA_IO_HUP, true, connection_data, this);
-+ fd, SPA_IO_ERR | SPA_IO_HUP, true,
-+ connection_data, this);
- if (this->source == NULL)
- goto cleanup_client;
-
-@@ -396,7 +418,7 @@ socket_data(void *data, int fd, enum spa_io mask)
-
- if (!client->busy)
- pw_loop_update_io(client->protocol->core->main_loop,
-- c->source, SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
-+ c->source, c->source->mask | SPA_IO_IN);
- }
-
- static bool add_socket(struct pw_protocol *protocol, struct server *s)
-@@ -479,6 +501,17 @@ on_remote_data(void *data, int fd, enum spa_io mask)
- res = -EPIPE;
- goto error;
- }
-+ if (mask & SPA_IO_OUT) {
-+ res = pw_protocol_native_connection_flush(conn);
-+ if (res >= 0) {
-+ int mask = impl->source->mask;
-+ SPA_FLAG_UNSET(mask, SPA_IO_OUT);
-+ pw_loop_update_io(core->main_loop,
-+ impl->source, mask);
-+ impl->flushing = false;
-+ } else if (res != EAGAIN)
-+ goto error;
-+ }
-
- if (mask & SPA_IO_IN) {
- const struct pw_protocol_native_message *msg;
-@@ -545,23 +578,17 @@ error:
- }
-
-
--static void do_flush_event(void *data, uint64_t count)
--{
-- struct client *impl = data;
-- impl->flush_signaled = false;
-- if (impl->connection)
-- if (pw_protocol_native_connection_flush(impl->connection) < 0)
-- impl->this.disconnect(&impl->this);
--}
--
- static void on_need_flush(void *data)
- {
- struct client *impl = data;
- struct pw_remote *remote = impl->this.remote;
-
-- if (!impl->flush_signaled) {
-- impl->flush_signaled = true;
-- pw_loop_signal_event(remote->core->main_loop, impl->flush_event);
-+ if (!impl->flushing) {
-+ int mask = impl->source->mask;
-+ impl->flushing = true;
-+ SPA_FLAG_SET(mask, SPA_IO_OUT);
-+ pw_loop_update_io(remote->core->main_loop,
-+ impl->source, mask);
- }
- }
-
-@@ -619,12 +646,9 @@ static void impl_disconnect(struct pw_protocol_client *client)
- static void impl_destroy(struct pw_protocol_client *client)
- {
- struct client *impl = SPA_CONTAINER_OF(client, struct client, this);
-- struct pw_remote *remote = client->remote;
-
- impl_disconnect(client);
-
-- pw_loop_destroy_source(remote->core->main_loop, impl->flush_event);
--
- if (impl->properties)
- pw_properties_free(impl->properties);
-
-@@ -665,8 +689,6 @@ impl_new_client(struct pw_protocol *protocol,
- this->disconnect = impl_disconnect;
- this->destroy = impl_destroy;
-
-- impl->flush_event = pw_loop_add_event(remote->core->main_loop, do_flush_event, impl);
--
- spa_list_append(&protocol->client_list, &this->link);
-
- return this;
-@@ -701,10 +723,23 @@ static void on_before_hook(void *_data)
- struct pw_protocol_server *this = &server->this;
- struct pw_client *client, *tmp;
- struct client_data *data;
-+ int res;
-
- spa_list_for_each_safe(client, tmp, &this->client_list, protocol_link) {
- data = client->user_data;
-- pw_protocol_native_connection_flush(data->connection);
-+
-+ res = pw_protocol_native_connection_flush(data->connection);
-+ if (res == -EAGAIN) {
-+ int mask = data->source->mask;
-+ SPA_FLAG_SET(mask, SPA_IO_OUT);
-+ pw_loop_update_io(client->protocol->core->main_loop,
-+ data->source, mask);
-+ } else if (res < 0) {
-+ pw_log_warn("client %p: could not flush: %s",
-+ data->client, spa_strerror(res));
-+ pw_client_destroy(client);
-+ }
-+
- }
- }
-
-diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c
-index cb592e41..8b9e919d 100644
---- a/src/modules/module-protocol-native/connection.c
-+++ b/src/modules/module-protocol-native/connection.c
-@@ -493,8 +493,6 @@ int pw_protocol_native_connection_flush(struct pw_protocol_native_connection *co
- continue;
- else {
- res = -errno;
-- pw_log_error("could not sendmsg on fd:%d n_fds:%d: %s",
-- conn->fd, n_fds, spa_strerror(res));
- goto exit;
- }
- }
---
-2.23.0
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire_git.bb b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire_git.bb
index 823da421..1a4e4eb9 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire_git.bb
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/pipewire/pipewire_git.bb
@@ -1,29 +1,17 @@
require pipewire.inc
-SRC_URI = "gitsm://github.com/PipeWire/pipewire;protocol=https;branch=work \
- file://0001-spa-include-install-missing-headers.patch \
- file://0002-extensions-implement-Endpoint-ClientEndpoint-interfa.patch \
- file://0003-pipewire-cli-add-support-for-printing-endpoint-info-.patch \
- file://0004-pipewire-cli-add-command-to-modify-endpoint-control-.patch \
- file://0005-arm-build-with-mno-unaligned-access.patch \
- file://0006-logger-print-timestamps-on-logged-messages.patch \
- file://0007-alsa-make-corrections-on-the-timeout-based-on-how-fa.patch \
- file://0008-audio-dsp-allow-mode-to-be-set-with-a-property.patch \
- file://0009-audioconvert-do-setup-internal-links-and-buffers-als.patch \
- file://0010-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch \
- file://0011-gst-pwaudioringbuffer-make-the-buffer-size-sensitive.patch \
- file://0012-gst-pwaudioringbuffer-request-pause-play-on-the-appr.patch \
- file://0013-gst-pwaudioringbuffer-wait-only-for-STREAM_STATE_CON.patch \
- file://0014-gst-pwaudiosink-set-the-default-latency-time-buffer-.patch \
- file://0015-audioconvert-fmtconvert-assume-F32-on-the-other-port.patch \
- file://0016-gst-pwaudioringbuffer-set-node.latency-to-get-schedu.patch \
- file://0017-connection-move-remaining-data-and-fds.patch \
- file://0018-protocol-improve-flushing.patch \
+SRC_URI = "git://gitlab.freedesktop.org/pipewire/pipewire.git;protocol=https;branch=master \
+ file://0001-meson-revert-version-check-to-require-meson-0.47-not.patch \
+ file://0002-arm-build-with-mno-unaligned-access.patch \
+ file://0003-gst-Implement-new-pwaudio-src-sink-elements-based-on.patch \
+ file://0004-audioconvert-always-assume-that-output-ports-are-NOT.patch \
+ file://0005-module-access-add-same-sec-label-mode.patch \
+ file://0006-alsa-pcm-call-reuse_buffers-when-resetting-the-state.patch \
"
-SRCREV = "4be788962e60891237f1f018627bf709ae3981e6"
+SRCREV = "b0932e687fc47e0872ca291531f2291d99042d70"
-PV = "0.2.90+git${SRCPV}+3"
+PV = "0.2.91+git${SRCPV}+2"
S = "${WORKDIR}/git"
RDEPENDS_${PN} += "virtual/pipewire-sessionmanager virtual/pipewire-config"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-sink.endpoint
new file mode 100644
index 00000000..4bc43574
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-sink.endpoint
@@ -0,0 +1,10 @@
+[match-node]
+priority = 0
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-source.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-source.endpoint
new file mode 100644
index 00000000..7657f6f4
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-audio-source.endpoint
@@ -0,0 +1,10 @@
+[match-node]
+priority = 0
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-input-audio.endpoint-link b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-input-audio.endpoint-link
new file mode 100644
index 00000000..4b70dc89
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-input-audio.endpoint-link
@@ -0,0 +1,7 @@
+[match-endpoint]
+priority = 0
+direction = "sink"
+media_class = "Stream/Input/Audio"
+
+[endpoint-link]
+keep = false
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-output-audio.endpoint-link b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-output-audio.endpoint-link
new file mode 100644
index 00000000..5d6428f9
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-default-output-audio.endpoint-link
@@ -0,0 +1,7 @@
+[match-endpoint]
+priority = 0
+direction = "source"
+media_class = "Stream/Output/Audio"
+
+[endpoint-link]
+keep = false
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-input-audio.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-input-audio.endpoint
new file mode 100644
index 00000000..2993f3e4
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-input-audio.endpoint
@@ -0,0 +1,9 @@
+[match-node]
+priority = 0
+properties = [
+ { name = "media.class", value = "Stream/Input/Audio" },
+]
+
+[endpoint]
+direction = "sink"
+type = "pw-audio-softdsp-endpoint"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-output-audio.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-output-audio.endpoint
new file mode 100644
index 00000000..1cf82ea0
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/00-stream-output-audio.endpoint
@@ -0,0 +1,9 @@
+[match-node]
+priority = 0
+properties = [
+ { name = "media.class", value = "Stream/Output/Audio" },
+]
+
+[endpoint]
+direction = "source"
+type = "pw-audio-softdsp-endpoint"
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-sink.endpoint
new file mode 100644
index 00000000..85a9b511
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-sink.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 1
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.path", value = "hw:0,0" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 1
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-source.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-source.endpoint
new file mode 100644
index 00000000..c77701c0
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/01-hw00-audio-source.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 1
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+ { name = "api.alsa.path", value = "hw:0,0" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
+priority = 1
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-sink.endpoint
new file mode 100644
index 00000000..afc4303e
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-sink.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 30
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.card.id", value = "ak4613" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 30
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-source.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-source.endpoint
new file mode 100644
index 00000000..ad568059
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-ak4613-audio-source.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 30
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+ { name = "api.alsa.card.id", value = "ak4613" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
+priority = 30
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-sink.endpoint
new file mode 100644
index 00000000..becd21e2
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-sink.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 30
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.card.id", value = "DRA7xx-EVM" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 30
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-source.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-source.endpoint
new file mode 100644
index 00000000..72ef4677
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-dra7xx-audio-source.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 30
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+ { name = "api.alsa.card.id", value = "DRA7xx-EVM" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
+priority = 30
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-rpi3-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-rpi3-audio-sink.endpoint
new file mode 100644
index 00000000..74e4d62e
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/30-rpi3-audio-sink.endpoint
@@ -0,0 +1,13 @@
+[match-node]
+priority = 30
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.card.name", value = "bcm2835 ALSA" },
+ { name = "api.alsa.pcm.name", value = "bcm2835 ALSA" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 30
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-fiberdyne-amp.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-fiberdyne-amp.endpoint
new file mode 100644
index 00000000..807ad468
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-fiberdyne-amp.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 40
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.card.id", value = "ep016ch" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 40
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-microchip-mic.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-microchip-mic.endpoint
new file mode 100644
index 00000000..bbfcd43a
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/40-microchip-mic.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 40
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+ { name = "api.alsa.card.id", value = "ep811ch" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
+priority = 40
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-sink.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-sink.endpoint
new file mode 100644
index 00000000..62e27909
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-sink.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 70
+properties = [
+ { name = "media.class", value = "Audio/Sink" },
+ { name = "api.alsa.card.driver", value = "USB-Audio" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "sink"
+streams = "playback.streams"
+priority = 70
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-source.endpoint b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-source.endpoint
new file mode 100644
index 00000000..505ae8d8
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/70-usb-audio-source.endpoint
@@ -0,0 +1,12 @@
+[match-node]
+priority = 70
+properties = [
+ { name = "media.class", value = "Audio/Source" },
+ { name = "api.alsa.card.driver", value = "USB-Audio" },
+]
+
+[endpoint]
+type = "pw-audio-softdsp-endpoint"
+direction = "source"
+streams = "capture.streams"
+priority = 70
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link
new file mode 100644
index 00000000..b5753a10
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-input-audio.endpoint-link
@@ -0,0 +1,11 @@
+[match-endpoint]
+priority = 75
+direction = "sink"
+name = "bluealsa*"
+media_class = "Stream/Input/Audio"
+properties = [
+ { name = "bluealsa.profile", value = "sco" },
+]
+
+[endpoint-link]
+keep = true
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link
new file mode 100644
index 00000000..d1b3cec0
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/bluealsa-output-audio.endpoint-link
@@ -0,0 +1,11 @@
+[match-endpoint]
+priority = 75
+direction = "source"
+name = "bluealsa*"
+media_class = "Stream/Output/Audio"
+properties = [
+ { name = "bluealsa.profile", value = "sco" },
+]
+
+[endpoint-link]
+keep = true
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/capture.streams b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/capture.streams
new file mode 100644
index 00000000..e7ce36f6
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/capture.streams
@@ -0,0 +1,3 @@
+[[streams]]
+name = "Default"
+priority = 25
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/playback.streams b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/playback.streams
new file mode 100644
index 00000000..c645416a
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/playback.streams
@@ -0,0 +1,31 @@
+[[streams]]
+name = "Multimedia"
+priority = 25
+
+[[streams]]
+name = "Speech-Low"
+priority = 30
+
+[[streams]]
+name = "Custom-Low"
+priority = 35
+
+[[streams]]
+name = "Navigation"
+priority = 50
+
+[[streams]]
+name = "Speech-High"
+priority = 60
+
+[[streams]]
+name = "Custom-High"
+priority = 65
+
+[[streams]]
+name = "Communication"
+priority = 75
+
+[[streams]]
+name = "Emergency"
+priority = 99
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf
new file mode 100644
index 00000000..e0975a81
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf
@@ -0,0 +1,30 @@
+# Register well-known SPA factories
+# These do not need to exist on the system to be registered
+add-spa-lib audio.convert* audioconvert/libspa-audioconvert
+add-spa-lib api.alsa.* alsa/libspa-alsa
+add-spa-lib api.v4l2.* v4l2/libspa-v4l2
+add-spa-lib api.bluez5.* bluez5/libspa-bluez5
+
+# the client-device pipewire module is needed for libwireplumber-module-monitor
+load-pipewire-module libpipewire-module-client-device
+
+# Session object implementation
+# This keeps track of the default input & output device endpoint
+load-module C libwireplumber-module-session
+
+# Basic pipewire integration - do not remove
+load-module C libwireplumber-module-pipewire
+
+# Grants access to security confined clients
+load-module C libwireplumber-module-client-permissions
+
+load-module C libwireplumber-module-monitor {
+ "factory": <"api.alsa.enum.udev">,
+ "flags": <["use-adapter", "activate-devices"]>
+}
+
+# Implements endpoint creation based on TOML configuration files
+load-module C libwireplumber-module-config-endpoint
+
+# Implements linking clients to devices based on TOML configuration files
+load-module C libwireplumber-module-config-policy
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf.in b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf.in
deleted file mode 100644
index 76a57419..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl/wireplumber.conf.in
+++ /dev/null
@@ -1,55 +0,0 @@
-# Basic pipewire integration - do not remove
-load-module C libwireplumber-module-pipewire
-
-# Grants access to security confined clients
-load-module C libwireplumber-module-client-permissions
-
-# Endpoint implementation for standard audio devices
-# using software conversions, mixing and volume controls
-load-module C libwireplumber-module-pw-audio-softdsp-endpoint
-
-# Endpoint that provides high-level volume controls for the AGL mixer
-# The streams specified here are the ones that will appear in the mixer.
-# They must match the stream names in the alsa-udev module,
-# except for "Master", which is treated specially.
-load-module C libwireplumber-module-mixer {
- "streams": <["Master", "Multimedia", "Speech-Low", "Custom-Low",
- "Navigation", "Speech-High", "Custom-High",
- "Communication", "Emergency"]>
-}
-
-# Monitors the ALSA devices that are discovered via udev
-# and creates softdsp-endopints for each one of them
-# The streams specified here are the ones that will be available for linking
-# clients. Currently, they are matched against the client's role string.
-load-module C libwireplumber-module-pw-alsa-udev {
- "streams": <["Multimedia", "Speech-Low", "Custom-Low",
- "Navigation", "Speech-High", "Custom-High",
- "Communication", "Emergency"]>
-}
-
-# Monitors the Audio clients that are discovered via pipewire
-# and creates simple-endpoints for each one of them
-load-module C libwireplumber-module-pw-audio-client
-
-# Implements linking clients to devices and maintains
-# information about the devices to be used.
-# Notes:
-# - Devices must be specified in hw:X,Y format, where X and Y are integers.
-# Things like hw:Intel,0 or paths are not understood.
-# - Roles and priorities can be arbitrary strings and arbitrary numbers
-# - Roles are matched against the stream names specified in the modules above.
-load-module C libwireplumber-module-simple-policy {
- "default-playback-device": <"PLAYBACK">,
- "default-capture-device": <"CAPTURE">,
- "role-priorities": <{
- "Multimedia": 1,
- "Speech-Low": 2,
- "Custom-Low": 3,
- "Navigation": 5,
- "Speech-High:": 7,
- "Custom-High": 8,
- "Communication": 9,
- "Emergency": 10
- }>
-}
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb
index 7ed9ea1a..cab61e49 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber-board-config-agl_git.bb
@@ -7,56 +7,42 @@ SECTION = "multimedia"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
-SRC_URI = "file://wireplumber.conf.in"
+SRC_URI = "\
+ file://wireplumber.conf \
+ file://00-audio-sink.endpoint \
+ file://00-audio-source.endpoint \
+ file://00-default-input-audio.endpoint-link \
+ file://00-default-output-audio.endpoint-link \
+ file://00-stream-input-audio.endpoint \
+ file://00-stream-output-audio.endpoint \
+ file://01-hw00-audio-sink.endpoint \
+ file://01-hw00-audio-source.endpoint \
+ file://30-ak4613-audio-sink.endpoint \
+ file://30-ak4613-audio-source.endpoint \
+ file://30-dra7xx-audio-sink.endpoint \
+ file://30-dra7xx-audio-source.endpoint \
+ file://30-rpi3-audio-sink.endpoint \
+ file://40-fiberdyne-amp.endpoint \
+ file://40-microchip-mic.endpoint \
+ file://70-usb-audio-sink.endpoint \
+ file://70-usb-audio-source.endpoint \
+ file://bluealsa-input-audio.endpoint-link \
+ file://bluealsa-output-audio.endpoint-link \
+ file://capture.streams \
+ file://playback.streams \
+"
PACKAGE_ARCH = "${MACHINE_ARCH}"
do_configure[noexec] = "1"
do_compile[noexec] = "1"
-#
-# For device names, any unique substring of the "endpoint" name is valid.
-# To list all endpoints:
-# export XDG_RUNTIME_DIR=/run/user/1001
-# pipewire-cli
-# > connect pipewire-0
-# > list-objects
-# ... and look for objects of type "PipeWire:Interface:Endpoint/0"
-#
-# For instance:
-# id 269, parent 40, type PipeWire:Interface:Endpoint/0
-# media.name = "USB Audio on WD15 Dock (hw:1,0 / node 5)"
-# media.class = "Audio/Sink"
-# id 270, parent 40, type PipeWire:Interface:Endpoint/0
-# media.name = "USB Audio on WD15 Dock (hw:1,0 / node 7)"
-# media.class = "Audio/Source"
-#
-# Audio/Sink endpoints are valid for playback
-# Audio/Source endpoints are valid for capture
-#
-# Wireplumber will first filter endpoints based on the media.class, depending
-# on whether the client is doing playback or capture and then it will look
-# for a sub-string match in the media.name
-#
-DEV_PLAYBACK = "hw:0,0"
-DEV_CAPTURE = "hw:0,0"
-
-DEV_PLAYBACK_dra7xx-evm = "DRA7xx-EVM"
-DEV_CAPTURE_dra7xx-evm = "DRA7xx-EVM"
-
-DEV_PLAYBACK_m3ulcb = "ak4613"
-DEV_CAPTURE_m3ulcb = "ak4613"
-
-DEV_PLAYBACK_h3ulcb = "ak4613"
-DEV_CAPTURE_h3ulcb = "ak4613"
-
-DEV_PLAYBACK_raspberrypi3 = "bcm2835 ALSA on bcm2835 ALSA"
-DEV_CAPTURE_raspberrypi3 = "hw:0,0"
-
do_install_append() {
- sed -e "s/PLAYBACK/${DEV_PLAYBACK}/" -e "s/CAPTURE/${DEV_CAPTURE}/" ${WORKDIR}/wireplumber.conf.in > ${WORKDIR}/wireplumber.conf
install -d ${D}/${sysconfdir}/wireplumber/
install -m 644 ${WORKDIR}/wireplumber.conf ${D}/${sysconfdir}/wireplumber/wireplumber.conf
+ install -m 644 ${WORKDIR}/*.endpoint ${D}/${sysconfdir}/wireplumber/
+ install -m 644 ${WORKDIR}/*.endpoint-link ${D}/${sysconfdir}/wireplumber/
+ install -m 644 ${WORKDIR}/*.streams ${D}/${sysconfdir}/wireplumber/
}
FILES_${PN} += "\
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch
new file mode 100644
index 00000000..726b35e7
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber/0001-Build-cpptoml-without-a-cmake-subproject.patch
@@ -0,0 +1,28 @@
+From e5efe3d4f0abc28251dac245ce0cf4124e7e2a12 Mon Sep 17 00:00:00 2001
+From: George Kiagiadakis <george.kiagiadakis@collabora.com>
+Date: Thu, 5 Dec 2019 17:59:44 +0200
+Subject: [PATCH] Build cpptoml without a cmake subproject
+
+Upstream-Status: Inappropriate
+---
+ meson.build | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/meson.build b/meson.build
+index 5a75d96..0b21377 100644
+--- a/meson.build
++++ b/meson.build
+@@ -24,9 +24,7 @@ else
+ wireplumber_config_dir = join_paths(get_option('prefix'), get_option('sysconfdir'), 'wireplumber')
+ endif
+
+-cmake = import('cmake')
+-cpptoml = cmake.subproject('cpptoml')
+-cpptoml_dep = cpptoml.dependency('cpptoml')
++cpptoml_dep = declare_dependency(include_directories: include_directories('subprojects/cpptoml'))
+
+ gobject_dep = dependency('gobject-2.0')
+ gmodule_dep = dependency('gmodule-2.0')
+--
+2.24.0
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb
index 2979d7e5..0e810b37 100644
--- a/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb
+++ b/meta-agl-devel/meta-pipewire/recipes-multimedia/wireplumber/wireplumber_git.bb
@@ -1,6 +1,6 @@
SUMMARY = "Session / Policy Manager for PipeWire"
-HOMEPAGE = "https://gitlab.freedesktop.org/gkiagia/wireplumber"
-BUGTRACKER = "https://gitlab.freedesktop.org/gkiagia/wireplumber/issues"
+HOMEPAGE = "https://gitlab.freedesktop.org/pipewire/wireplumber"
+BUGTRACKER = "https://gitlab.freedesktop.org/pipewire/wireplumber/issues"
AUTHOR = "George Kiagiadakis <george.kiagiadakis@collabora.com>"
SECTION = "multimedia"
@@ -11,12 +11,22 @@ inherit meson pkgconfig gobject-introspection
DEPENDS = "glib-2.0 glib-2.0-native pipewire"
-SRC_URI = "git://gitlab.freedesktop.org/gkiagia/wireplumber;protocol=https;branch=0.1"
-SRCREV = "50db6a5930d01e9f34dda6952654ee4cb7926405"
+SRC_URI = "\
+ git://gitlab.freedesktop.org/pipewire/wireplumber.git;protocol=https;branch=master \
+ https://raw.githubusercontent.com/skystrife/cpptoml/fededad7169e538ca47e11a9ee9251bc361a9a65/include/cpptoml.h \
+ file://0001-Build-cpptoml-without-a-cmake-subproject.patch \
+"
+SRCREV = "0e98e4150b73d0bed9b72bf8d3eba49671962991"
+SRC_URI[sha256sum] = "3e4e1d315fa1229921c7a4297ead08775b5bb1220c18a7eac62db9ca7e79df0d"
-PV = "0.1.1+git${SRCPV}"
+PV = "0.1.90+git${SRCPV}"
S = "${WORKDIR}/git"
+do_configure_prepend() {
+ mkdir -p ${WORKDIR}/git/subprojects/cpptoml/include
+ cp -f ${WORKDIR}/cpptoml.h ${WORKDIR}/git/subprojects/cpptoml/include/
+}
+
PACKAGES =+ "${PN}-config"
FILES_${PN} += "\
diff --git a/meta-agl-devel/meta-pipewire/recipes-security/cynagora/cynagora_%.bbappend b/meta-agl-devel/meta-pipewire/recipes-security/cynagora/cynagora_%.bbappend
new file mode 100644
index 00000000..9395c90c
--- /dev/null
+++ b/meta-agl-devel/meta-pipewire/recipes-security/cynagora/cynagora_%.bbappend
@@ -0,0 +1,5 @@
+
+do_install_append() {
+ echo "System::Pipewire * * http://tizen.org/privilege/internal/dbus yes forever" >> ${D}${sysconfdir}/security/cynagora.initial
+}
+
diff --git a/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager/0001-Adapt-smack-rules-to-allow-connections-to-pipewire.patch b/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager/0001-Adapt-smack-rules-to-allow-connections-to-pipewire.patch
deleted file mode 100644
index 821c1e1d..00000000
--- a/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager/0001-Adapt-smack-rules-to-allow-connections-to-pipewire.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From cc5cbaddad6fe559e9e482467266fb18fb00c6a7 Mon Sep 17 00:00:00 2001
-From: George Kiagiadakis <george.kiagiadakis@collabora.com>
-Date: Wed, 26 Jun 2019 16:02:13 +0300
-Subject: [PATCH] Adapt smack rules to allow connections to pipewire
-
-Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
----
- policy/app-rules-template.smack | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/policy/app-rules-template.smack b/policy/app-rules-template.smack
-index 910f40c..78b75de 100644
---- a/policy/app-rules-template.smack
-+++ b/policy/app-rules-template.smack
-@@ -4,6 +4,7 @@ System ~PKG~ rwxat
- ~APP~ System::Shared rx
- ~APP~ System::Run rwxat
- ~APP~ System::Log rwxa
-+~APP~ System::Pipewire rw
- ~APP~ _ l
- ~APP~ User::Home rxl
- ~APP~ User::App-Shared rwxat
---
-2.20.1
-
diff --git a/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager_%.bbappend b/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager_%.bbappend
index 319a27d6..59449446 100644
--- a/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager_%.bbappend
+++ b/meta-agl-devel/meta-pipewire/recipes-security/security-manager/security-manager_%.bbappend
@@ -1,2 +1,4 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/security-manager:"
-SRC_URI += "file://0001-Adapt-smack-rules-to-allow-connections-to-pipewire.patch"
+
+do_install_append() {
+ echo "~APP~ System::Pipewire rw" >> ${D}${datadir}/security-manager/policy/app-rules-template.smack
+}
diff --git a/meta-agl-devel/meta-speech-framework/conf/include/agl-speech-framework.inc b/meta-agl-devel/meta-speech-framework/conf/include/agl-speech-framework.inc
index 9b7a0f07..ee19d25f 100644
--- a/meta-agl-devel/meta-speech-framework/conf/include/agl-speech-framework.inc
+++ b/meta-agl-devel/meta-speech-framework/conf/include/agl-speech-framework.inc
@@ -1,2 +1 @@
-# Currently no default voiceagent
-PREFERRED_RPROVIDER_virtual/voiceagent ?= ""
+PREFERRED_RPROVIDER_virtual/voice-high-config = "default-voice-high-config"
diff --git a/meta-agl-devel/meta-speech-framework/conf/include/agl-voiceagent-alexa.inc b/meta-agl-devel/meta-speech-framework/conf/include/agl-voiceagent-alexa.inc
index ad509d14..10df0926 100644
--- a/meta-agl-devel/meta-speech-framework/conf/include/agl-voiceagent-alexa.inc
+++ b/meta-agl-devel/meta-speech-framework/conf/include/agl-voiceagent-alexa.inc
@@ -3,4 +3,8 @@
# agl-voiceagent-alexa is configured.
BBMASK += "meta-aac/recipes-support/curl/curl_%.bbappend"
-PREFERRED_RPROVIDER_virtual/voiceagent = "alexa-voiceagent-service"
+PREFERRED_RPROVIDER_virtual/voice-high-config = "alexa-voice-high-config"
+
+FEATURE_PACKAGES_agl-voiceagent-alexa = "packagegroup-agl-voiceagent-alexa"
+
+IMAGE_FEATURES += "agl-voiceagent-alexa"
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac-amazonlite/recipes-wakeword/pryon-lite/pryon-lite.bbappend b/meta-agl-devel/meta-speech-framework/meta-aac-amazonlite/recipes-wakeword/pryon-lite/pryon-lite.bbappend
new file mode 100644
index 00000000..ceba2eb2
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac-amazonlite/recipes-wakeword/pryon-lite/pryon-lite.bbappend
@@ -0,0 +1,2 @@
+# Required to avoid QA errors from the prebuilt libraries
+INSANE_SKIP_${PN} += "ldflags"
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config/voice-high.json b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config/voice-high.json
new file mode 100644
index 00000000..f460ccfc
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config/voice-high.json
@@ -0,0 +1 @@
+{ "default": "VA-001" }
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config_1.0.bb b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config_1.0.bb
new file mode 100644
index 00000000..736a7ce5
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voice-high-config_1.0.bb
@@ -0,0 +1,20 @@
+SUMMARY = "High level voice service binding default voiceagent configuration for Alexa"
+DESCRIPTION = "Alexa default voiceagent JSON configuration file for agl-service-voice-high binding"
+HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high"
+SECTION = "apps"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+SRC_URI = "file://voice-high.json"
+
+inherit allarch
+
+do_compile[noexec] = "1"
+
+do_install () {
+ install -D -m 644 ${WORKDIR}/voice-high.json ${D}${sysconfdir}/xdg/AGL/voice-high.json
+}
+
+RPROVIDES_${PN} += "virtual/voice-high-config"
+
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config/AlexaAutoCoreEngineConfig.json.in b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config/AlexaAutoCoreEngineConfig.json.in
new file mode 100644
index 00000000..9ead4893
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config/AlexaAutoCoreEngineConfig.json.in
@@ -0,0 +1,184 @@
+{
+ "deviceInfo":
+ {
+ "clientId":"@@ALEXA_CLIENTID@@",
+ "deviceSerialNumber":"@@ALEXA_SERIALNUMBER@@",
+ "productId":"@@ALEXA_PRODUCTID@@"
+ },
+ "libcurlUtils":
+ {
+ "CURLOPT_CAPATH":"/etc/ssl/certs"
+ },
+ "miscDatabase":
+ {
+ "databaseFilePath":"./miscDatabase.db"
+ },
+ "certifiedSender":
+ {
+ "databaseFilePath":"./certifiedSender.db"
+ },
+ "alertsCapabilityAgent":
+ {
+ "databaseFilePath":"./alertsCapabilityAgent.db"
+ },
+ "notifications":
+ {
+ "databaseFilePath":"./notifications.db"
+ },
+ "settings":
+ {
+ "databaseFilePath":"./settings.db",
+ "defaultAVSClientSettings":
+ {
+ "locale":"en-US"
+ }
+ },
+ "aace.storage": {
+ "localStoragePath": "./sample-aace.db",
+ "storageType": "sqlite"
+ },
+ "aace.vehicle": {
+ "info": {
+ "make": "Amazon",
+ "model": "AACE",
+ "year": "2018",
+ "trim": "aac",
+ "geography": "US",
+ "version": "1.2.3",
+ "os": "sample-aace",
+ "arch": "sample-aace",
+ "language": "en_US",
+ "microphone": "SingleArray",
+ "countries": "US,GB,IE,CA,DE,AT,IN,JP,AU,NZ,FR"
+ },
+ "operatingCountry": "US",
+ "currentLocation": "36.1363,-115.1513"
+ },
+ "aace.audio.input": {
+ "voice": "Default"
+ },
+ "aace.audio.output": {
+ "tts": "Speech-High",
+ "music": "Speech-Low"
+ },
+ "aace.wakeword": {
+ "enabled":@@WAKEWORD@@
+ },
+ "aace.cbl": {
+ "enabled": true
+ },
+ "aace.localmediasource": {
+ "enabled":false,
+ "sources": {
+ "bluetooth":false,
+ "usb":false,
+ "fmRadio":false,
+ "amRadio":false,
+ "satelliteRadio":false,
+ "lineIn":false,
+ "compactDisc":false
+ }
+ },
+ "aace.localvoicecontrol": {
+ "enabled":false,
+ "socketRootDirectory":"/var/"
+ },
+ "aace.localskills": {
+ "aace.carcontrol": {
+ "enabled": false,
+ "cannedzones": [
+ {
+ "name" : "zone.all",
+ "enabled": true,
+ "climate": {
+ "syncController": false,
+ "recirculationController": false
+ },
+ "airconditioner" : {
+ "modes": {
+ "AUTO": true,
+ "ECONOMY": false,
+ "MANUAL": false,
+ "MAXIMIUM": false
+ }
+ },
+ "heater" : {
+ "minimum": 60.0,
+ "maximum": 80.0,
+ "precision": 1.0,
+ "unit": "FAHRENHEIT"
+ },
+ "fan" : {
+ "minimum": 0.0,
+ "maximium": 10.0,
+ "precision": 1.0
+ },
+ "vent": {
+ "positions" : {
+ "BODY": true,
+ "MIX": false,
+ "FLOOR": false,
+ "WINDSHIELD": false
+ }
+ },
+ "window" : {
+ "defrost": true
+ },
+ "light" : {
+ "type": "LIGHT",
+ "colors" : {
+ "WHITE": true,
+ "RED": true,
+ "ORANGE": true,
+ "YELLOW": true,
+ "GREEN": true,
+ "BLUE": true,
+ "INDIGO": true,
+ "VIOLET": true
+ }
+ }
+ },
+ {
+ "name" : "zone.back.driver",
+ "enabled": false
+ },
+ {
+ "name" : "zone.back.passenger",
+ "enabled": false
+ },
+ {
+ "name" : "zone.driver",
+ "enabled": false
+ },
+ {
+ "name" : "zone.first.row",
+ "enabled": false
+ },
+ {
+ "name" : "zone.fourth.row",
+ "enabled": false
+ },
+ {
+ "name" : "zone.front",
+ "enabled": false
+ },
+ {
+ "name" : "zone.passenger",
+ "enabled": false
+ },
+ {
+ "name" : "zone.rear",
+ "enabled": false
+ },
+ {
+ "name" : "zone.second.row",
+ "enabled": false
+ },
+ {
+ "name" : "zone.third.row",
+ "enabled": false
+ }
+ ]
+ }
+ }
+}
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config_1.0.bb b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config_1.0.bb
new file mode 100644
index 00000000..7e5992bb
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-config_1.0.bb
@@ -0,0 +1,40 @@
+SUMMARY = "Alexa service binding default configuration to connect to Alexa"
+DESCRIPTION = "Alexa alexa-voiceagent-service binding configuration files"
+HOMEPAGE = "https://github.com/alexa/alexa-auto-sdk/tree/master/platforms/agl/alexa-voiceagent-service"
+SECTION = "apps"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+SRC_URI = "file://AlexaAutoCoreEngineConfig.json.in"
+
+inherit allarch
+
+ALEXA_WAKEWORD ??= "false"
+
+do_compile () {
+
+ if test x"${ALEXA_CLIENTID}" == x"" ; then
+ bbfatal "ALEXA CLIENTID not defined in your environment e.g. conf/local.conf"
+ fi
+
+ if test x"${ALEXA_SERIALNUMBER}" == x"" ; then
+ bbfatal "ALEXA SERIALNUMBER not defined in your environment e.g. conf/local.conf"
+ fi
+
+ if test x"${ALEXA_PRODUCTID}" == x"" ; then
+ bbfatal "ALEXA PRODUCTID not defined in your environment e.g. conf/local.conf"
+ fi
+
+}
+
+do_install () {
+ #replace
+ sed -e "s/@@ALEXA_CLIENTID@@/${ALEXA_CLIENTID}/" -e "s/@@ALEXA_SERIALNUMBER@@/${ALEXA_SERIALNUMBER}/" -e "s/@@ALEXA_PRODUCTID@@/${ALEXA_PRODUCTID}/" -e "s/@@WAKEWORD@@/${ALEXA_WAKEWORD}/" ${WORKDIR}/AlexaAutoCoreEngineConfig.json.in > ${WORKDIR}/AlexaAutoCoreEngineConfig.json
+
+ # install
+ install -D -m 644 ${WORKDIR}/AlexaAutoCoreEngineConfig.json ${D}${sysconfdir}/xdg/AGL/AlexaAutoCoreEngineConfig.json
+}
+
+RPROVIDES_${PN} += "virtual/alexa-voiceagent-config"
+
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0001-remove-library-dependency-copying.patch b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0001-remove-library-dependency-copying.patch
index 7b0141c4..3e45c527 100644
--- a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0001-remove-library-dependency-copying.patch
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0001-remove-library-dependency-copying.patch
@@ -9,11 +9,11 @@ Upstream-Status: Inappropriate [embedded specific]
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-diff --git a/platforms/agl/alexa-voiceagent-service/libs/CMakeLists.txt b/platforms/agl/alexa-voiceagent-service/libs/CMakeLists.txt
-index 4732e7b..ffc149d 100644
+diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
+index 4732e7b..938e5f3 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
-@@ -70,14 +70,6 @@ add_avs_library(SpeechEncoder ${AAC_HOME}/lib/libSpeechEncoder.so)
+@@ -70,22 +70,13 @@ add_avs_library(SpeechEncoder ${AAC_HOME}/lib/libSpeechEncoder.so)
add_avs_library(OpusEncoderContext ${AAC_HOME}/lib/libOpusEncoderContext.so)
add_avs_library(SpeechSynthesizer ${AAC_HOME}/lib/libSpeechSynthesizer.so)
add_avs_library(TemplateRuntime ${AAC_HOME}/lib/libTemplateRuntime.so)
@@ -28,3 +28,12 @@ index 4732e7b..ffc149d 100644
add_avs_library(equalizer ${AAC_HOME}/lib/libEqualizer.so)
add_avs_library(EqualizerImplementations ${AAC_HOME}/lib/libEqualizerImplementations.so)
+-if(EXISTS ${AAC_HOME}/lib/libpryon_lite.so.1.13)
++if(EXISTS ${AAC_HOME}/lib/libAACEAmazonLiteEngine.so)
+ add_aace_library(AACEAmazonLiteEngine)
+ add_avs_library(AMAZONLITE ${AAC_HOME}/lib/libAMAZONLITE.so)
+ add_avs_library(KeywordDetectorProvider ${AAC_HOME}/lib/libKeywordDetectorProvider.so)
+- add_avs_library(pryon_lite ${AAC_HOME}/lib/libpryon_lite.so.1.13)
+ endif()
+
+ if(EXISTS ${AAC_HOME}/lib/libAACEGStreamerEngine.so)
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0005-fix-segmentation-fault-for-release-build-mode.patch b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0005-fix-segmentation-fault-for-release-build-mode.patch
new file mode 100644
index 00000000..5012dfe8
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0005-fix-segmentation-fault-for-release-build-mode.patch
@@ -0,0 +1,33 @@
+Fix segmentation fault for release build mode
+
+'int IAFBApi::callSync(...)' is missing a return
+statement. When the sdk is compiled in release mode
+executing this code results in a segmentation fault.
+
+According to the C++ standard, a return statement is
+required on a function that returns a non-void value.
+Specifically: <<Flowing off the end of a function is
+equivalent to a return with no value; this results in
+undefined behaviour in a value-returning function.>>
+
+The proposed fix provides the missing return statement
+for IAFBApi's callSync method.
+
+Upstream-Status: Pending
+
+Signed-off-by: Raquel Medina <raquel.medina@konsulko.com>
+
+diff --git a/platforms/agl/alexa-voiceagent-service/src/plugins/afb/AFBApiImpl.cpp b/platforms/agl/alexa-voiceagent-service/src/plugins/afb/AFBApiImpl.cpp
+index 5ed9bce..e68ef7f 100644
+--- a/src/plugins/afb/AFBApiImpl.cpp
++++ b/src/plugins/afb/AFBApiImpl.cpp
+@@ -77,6 +77,8 @@ int AFBApiImpl::callSync(
+ info = infoStr;
+ free(infoStr);
+ }
++
++ return rc;
+ }
+
+ /// Shim to transfer C++ function to C callback using void*
+
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0006-fix-event-argument-json.patch b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0006-fix-event-argument-json.patch
new file mode 100644
index 00000000..8c6f1e4b
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/0006-fix-event-argument-json.patch
@@ -0,0 +1,183 @@
+Fix event argument JSON
+
+It was discovered while trying to use some of the capabilities events
+that the argument JSON was incorrectly formatted, with instances of
+all or part of it being double-quoted as strings with escaping. A
+couple instances of this had previously been worked around by hacks
+involving reparsing all or some parts of the arguments a second time
+with a JSON parser, but it seems better to fix it at the source so
+that the events match documentation and are usable as is.
+
+Note that it is ATM not clear if all affected event argument payloads
+are correct, e.g. LocalMediaSource may need some more work.
+
+Upstream-Status: Pending
+
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+
+diff --git a/src/plugins/aasb-client/AlexaCapabilityDirectiveRouterImpl.cpp b/src/plugins/aasb-client/AlexaCapabilityDirectiveRouterImpl.cpp
+index 6aea920..23ed90c 100644
+--- a/src/plugins/aasb-client/AlexaCapabilityDirectiveRouterImpl.cpp
++++ b/src/plugins/aasb-client/AlexaCapabilityDirectiveRouterImpl.cpp
+@@ -17,6 +17,8 @@
+
+ #include <sstream>
+
++#include <json-c/json.h>
++
+ #include <aasb/Consts.h>
+
+ #include "AlexaConsts.h"
+@@ -322,7 +324,16 @@ void AlexaCapabilityDirectiveRouterImpl::processTemplateRuntimeAction(
+
+ json_object* argsJ = json_object_new_object();
+ json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
+- json_object* payloadJ = json_object_new_string(payload.c_str());
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+
+@@ -343,24 +354,40 @@ void AlexaCapabilityDirectiveRouterImpl::processCBLAction(
+ const std::string& payload) {
+ m_logger->log(Level::DEBUG, TAG, "Processing CBL action: " + action);
+
+- json_object* eventDataJ = json_object_new_object();
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
++ // The payload string may already be of the form of a document like
++ // "{ "payload" : { ... } }", the simplest way to handle that is to use
++ // it as the event json_object if that's the case, that way we avoid
++ // having to worry about copying.
++ json_object* eventDataJ = NULL;
++ if(json_object_object_get_ex(payloadJ, "payload", NULL)) {
++ eventDataJ = payloadJ;
++ } else {
++ eventDataJ = json_object_new_object();
++ json_object_object_add(eventDataJ, JSON_ATTR_PAYLOAD.c_str(), payloadJ);
++ }
+ json_object* vaIdJ = json_object_new_string(m_alexaVoiceAgentId.c_str());
+-
+ json_object_object_add(eventDataJ, JSON_ATTR_VOICEAGENT_ID.c_str(), vaIdJ);
+
+ int observers = 0;
+ if (action == aasb::bridge::ACTION_CBL_CODEPAIR_RECEIVED) {
+ m_logger->log(Level::INFO, TAG, "CBL codepair received: " + payload);
+- json_object* payloadJ = json_object_new_string(payload.c_str());
+- json_object_object_add(eventDataJ, JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+ observers = m_cblCodePairReceivedEvent->publishEvent(eventDataJ);
+ } else if (action == aasb::bridge::ACTION_CBL_CODEPAIR_EXPIRED) {
+ m_logger->log(Level::INFO, TAG, "CBL codepair expired: " + payload);
+- json_object* payloadJ = json_object_new_string(payload.c_str());
+- json_object_object_add(eventDataJ, JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+ observers = m_cblCodePairExpiredEvent->publishEvent(eventDataJ);
+ } else {
+ m_logger->log(Level::INFO, TAG, "Unhandled action: " + action);
++ json_object_put(eventDataJ);
+ }
+
+ std::stringstream logMsg;
+diff --git a/src/plugins/dispatchers/local-voice-control/car-control/CarControlDispatcher.cpp b/src/plugins/dispatchers/local-voice-control/car-control/CarControlDispatcher.cpp
+index 096f72f..75108d4 100644
+--- a/src/plugins/dispatchers/local-voice-control/car-control/CarControlDispatcher.cpp
++++ b/src/plugins/dispatchers/local-voice-control/car-control/CarControlDispatcher.cpp
+@@ -72,7 +72,16 @@ void CarControlDispatcher::onReceivedDirective(
+
+ json_object* argsJ = json_object_new_object();
+ json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
+- json_object* payloadJ = json_object_new_string(payload.c_str());
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+
+diff --git a/src/plugins/dispatchers/localmediasource/LocalMediaSourceDispatcher.cpp b/src/plugins/dispatchers/localmediasource/LocalMediaSourceDispatcher.cpp
+index c261a56..04ac10c 100644
+--- a/src/plugins/dispatchers/localmediasource/LocalMediaSourceDispatcher.cpp
++++ b/src/plugins/dispatchers/localmediasource/LocalMediaSourceDispatcher.cpp
+@@ -71,7 +71,16 @@ void LocalMediaSourceDispatcher::onReceivedDirective(
+
+ json_object* argsJ = json_object_new_object();
+ json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
+- json_object* payloadJ = json_object_new_string(payload.c_str());
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+
+diff --git a/src/plugins/dispatchers/navigation/NavigationDispatcher.cpp b/src/plugins/dispatchers/navigation/NavigationDispatcher.cpp
+index 55a6017..283b42b 100644
+--- a/src/plugins/dispatchers/navigation/NavigationDispatcher.cpp
++++ b/src/plugins/dispatchers/navigation/NavigationDispatcher.cpp
+@@ -68,7 +68,16 @@ void NavigationDispatcher::onReceivedDirective(
+
+ json_object* argsJ = json_object_new_object();
+ json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
+- json_object* payloadJ = json_object_new_string(payload.c_str());
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+
+diff --git a/src/plugins/dispatchers/phonecall/PhoneCallDispatcher.cpp b/src/plugins/dispatchers/phonecall/PhoneCallDispatcher.cpp
+index 29ad96a..3432892 100644
+--- a/src/plugins/dispatchers/phonecall/PhoneCallDispatcher.cpp
++++ b/src/plugins/dispatchers/phonecall/PhoneCallDispatcher.cpp
+@@ -86,7 +86,16 @@ void PhoneCallDispatcher::onReceivedDirective(
+
+ json_object* argsJ = json_object_new_object();
+ json_object* actionJ = json_object_new_string(vshlCapabilityAction.c_str());
+- json_object* payloadJ = json_object_new_string(payload.c_str());
++ json_object* payloadJ = NULL;
++ if(payload.length()) {
++ payloadJ = json_tokener_parse(payload.c_str());
++ } else {
++ payloadJ = json_object_new_string("");
++ }
++ if(!payloadJ) {
++ m_logger->log(Level::ERROR, TAG, "Unable to parse payload JSON: " + payload);
++ return;
++ }
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_ACTION.c_str(), actionJ);
+ json_object_object_add(argsJ, agl::alexa::JSON_ATTR_PAYLOAD.c_str(), payloadJ);
+
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/alexa.json b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/alexa.json
new file mode 100644
index 00000000..48918015
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service/alexa.json
@@ -0,0 +1,14 @@
+{
+ "id": "VA-001",
+ "active": true,
+ "name": "Alexa",
+ "api": "alexa-voiceagent",
+ "wakewords": [
+ "alexa",
+ "computer",
+ "echo"
+ ],
+ "activewakeword": "alexa",
+ "description": "Alexa voice assistant by Amazon.",
+ "vendor": "Amazon.com Services Inc"
+}
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service_git.bb b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service_git.bb
index 296cf2d2..f0211552 100644
--- a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service_git.bb
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-apis/alexa-voiceagent-service/alexa-voiceagent-service_git.bb
@@ -17,13 +17,17 @@ DEPENDS = " \
aac-module-navigation \
aac-module-phone-control \
aac-module-gstreamer \
+ ${@bb.utils.contains("ALEXA_WAKEWORD", "true", "aac-module-amazonlite pryon-lite", "", d)} \
"
SRC_URI = "git://github.com/alexa/alexa-auto-sdk.git;protocol=https;branch=2.0 \
+ file://alexa.json \
file://0001-remove-library-dependency-copying.patch \
file://0002-update-config.xml.in.patch \
file://0003-update-audio-device-configuration.patch \
file://0004-update-config-and-database-paths.patch \
+ file://0005-fix-segmentation-fault-for-release-build-mode.patch \
+ file://0006-fix-event-argument-json.patch \
"
SRCREV = "86916d2d8c1702a8be3c88a9012ca56583bcc0c8"
@@ -34,8 +38,23 @@ inherit cmake aglwgt
EXTRA_OECMAKE += "-DAAC_HOME=${RECIPE_SYSROOT}/${AAC_PREFIX}"
+ALEXA_WAKEWORD ??= "false"
+
+do_install_append() {
+ install -D -m 0644 ${WORKDIR}/alexa.json ${D}${sysconfdir}/xdg/AGL/voiceagents/alexa.json
+}
+
+PACKAGES =+ "${PN}-conf"
+
+FILES_${PN}-conf = "${sysconfdir}/xdg/AGL/voiceagents/*"
+
# NOTE: curl and opus are from the base SDK libraries, sqlite3 from the
# core module
-RDEPENDS_${PN} += "libcurl libopus libsqlite3"
-
-RPROVIDES_${PN} += "virtual/voiceagent"
+RDEPENDS_${PN} += " \
+ libcurl \
+ libopus \
+ libsqlite3 \
+ ${PN}-conf \
+ ${@bb.utils.contains("ALEXA_WAKEWORD", "true", "pryon-lite", "", d)} \
+ gstreamer1.0-plugins-bad-hls \
+"
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend
new file mode 100644
index 00000000..43836942
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend
@@ -0,0 +1,4 @@
+RDEPENDS_${PN} += " \
+ alexa-voiceagent-service \
+ ${@bb.utils.contains("DISTRO_FEATURES", "agl-demo-preload", "virtual/alexa-voiceagent-config", "",d)} \
+"
diff --git a/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-voiceagent-alexa.bb b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-voiceagent-alexa.bb
new file mode 100644
index 00000000..5f38e7ef
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/meta-aac/recipes-platform/packagegroups/packagegroup-agl-voiceagent-alexa.bb
@@ -0,0 +1,15 @@
+SUMMARY = "The software for the AGL Alexa voiceagent feature"
+DESCRIPTION = "The software for the AGL Alexa voiceagent feature"
+
+LICENSE = "MIT"
+
+inherit packagegroup
+
+PACKAGES = "\
+ packagegroup-agl-voiceagent-alexa \
+"
+
+RDEPENDS_${PN} += " \
+ alexa-voiceagent-service \
+ ${@bb.utils.contains("DISTRO_FEATURES", "agl-demo-preload", "virtual/alexa-voiceagent-config", "",d)} \
+"
diff --git a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high-capabilities/agl-service-voice-high-capabilities_git.bb b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high-capabilities/agl-service-voice-high-capabilities_git.bb
index efeba097..6ab4da9c 100644
--- a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high-capabilities/agl-service-voice-high-capabilities_git.bb
+++ b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high-capabilities/agl-service-voice-high-capabilities_git.bb
@@ -6,14 +6,12 @@ SECTION = "apps"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
-inherit cmake pkgconfig aglwgt
-
-DEPENDS += "lua lua-native"
-RDEPENDS_${PN} += "lua"
+DEPENDS = "libafb-helpers libappcontroller nlohmann-json"
-SRC_URI = "gitsm://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high-capabilities.git;protocol=https;branch=${AGL_BRANCH}"
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high-capabilities.git;protocol=https;branch=${AGL_BRANCH}"
SRCREV = "${AGL_APP_REVISION}"
PV = "0.1+git${SRCPV}"
S = "${WORKDIR}/git"
+inherit cmake pkgconfig aglwgt
diff --git a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/agl-service-voice-high_git.bb b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/agl-service-voice-high_git.bb
index 9b9fa928..b8ee77fd 100644
--- a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/agl-service-voice-high_git.bb
+++ b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/agl-service-voice-high_git.bb
@@ -6,7 +6,9 @@ SECTION = "apps"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://License.txt;md5=3b83ef96387f14655fc854ddc3c6bd57"
-SRC_URI = "gitsm://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high;protocol=https;branch=${AGL_BRANCH}"
+DEPENDS = "json-c systemd af-binder libafb-helpers libappcontroller nlohmann-json glib-2.0"
+
+SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high;protocol=https;branch=${AGL_BRANCH}"
SRCREV = "${AGL_APP_REVISION}"
PV = "1.0+git${SRCPV}"
@@ -14,4 +16,3 @@ S = "${WORKDIR}/git"
inherit cmake aglwgt
-DEPENDS += "json-c systemd af-binder glib-2.0 lua"
diff --git a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config/voice-high.json b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config/voice-high.json
new file mode 100644
index 00000000..1b72b8c8
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config/voice-high.json
@@ -0,0 +1 @@
+{ "default": "" }
diff --git a/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config_1.0.bb b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config_1.0.bb
new file mode 100644
index 00000000..b015dd5d
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/recipes-apis/agl-service-voice-high/default-voice-high-config_1.0.bb
@@ -0,0 +1,20 @@
+SUMMARY = "High level voice service binding default voiceagent configuration"
+DESCRIPTION = "Default voiceagent JSON configuration file for agl-service-voice-high binding"
+HOMEPAGE = "https://gerrit.automotivelinux.org/gerrit/apps/agl-service-voice-high"
+SECTION = "apps"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+SRC_URI = "file://voice-high.json"
+
+inherit allarch
+
+do_compile[noexec] = "1"
+
+do_install () {
+ install -D -m 644 ${WORKDIR}/voice-high.json ${D}${sysconfdir}/xdg/AGL/voice-high.json
+}
+
+RPROVIDES_${PN} += "virtual/voice-high-config"
+
diff --git a/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-core-services.bbappend b/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-core-services.bbappend
deleted file mode 100644
index 42fc5e58..00000000
--- a/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-core-services.bbappend
+++ /dev/null
@@ -1,7 +0,0 @@
-# Checking PREFERRED_RPROVIDER_virtual/voiceagent below is less than ideal, but
-# seems required until there is a usable default voiceagent.
-RDEPENDS_${PN} += " \
- agl-service-voice-high \
- agl-service-voice-high-capabilities \
- ${@oe.utils.conditional("PREFERRED_RPROVIDER_virtual/voiceagent", "", "", "virtual/voiceagent", d)} \
-"
diff --git a/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend b/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend
new file mode 100644
index 00000000..7e918671
--- /dev/null
+++ b/meta-agl-devel/meta-speech-framework/recipes-platform/packagegroups/packagegroup-agl-ivi-services.bbappend
@@ -0,0 +1,5 @@
+RDEPENDS_${PN} += " \
+ agl-service-voice-high \
+ agl-service-voice-high-capabilities \
+ ${PREFERRED_RPROVIDER_virtual/voice-high-config} \
+"
diff --git a/meta-agl-devel/templates/feature/agl-html5-framework/50_bblayers.conf.inc b/meta-agl-devel/templates/feature/agl-html5-framework/50_bblayers.conf.inc
deleted file mode 100644
index 952ef4ea..00000000
--- a/meta-agl-devel/templates/feature/agl-html5-framework/50_bblayers.conf.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-
-BBLAYERS =+ " \
- ${METADIR}/meta-agl-devel/meta-html5-framework \
- "
-
diff --git a/meta-agl-devel/templates/feature/agl-html5-framework/README_feature_agl-html5-framework.md b/meta-agl-devel/templates/feature/agl-html5-framework/README_feature_agl-html5-framework.md
deleted file mode 100644
index d992009c..00000000
--- a/meta-agl-devel/templates/feature/agl-html5-framework/README_feature_agl-html5-framework.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-description: Feature agl-html5-framework
-authors: Jacobo Aragunde Pérez <jaragunde@igalia.com>
----
-
-### Feature agl-html5-framework
-
-*Description is missing - please complete file meta-agl-devel/templates/feature/agl-html5-framework/README_feature_agl-html5-framework.md*
-
diff --git a/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_bblayers.conf.inc b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_bblayers.conf.inc
new file mode 100644
index 00000000..a7e9da1d
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_bblayers.conf.inc
@@ -0,0 +1,5 @@
+
+BBLAYERS =+ " \
+ ${METADIR}/meta-agl-devel/meta-agl-profile-graphical-html5 \
+ "
+
diff --git a/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_local.conf.inc b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_local.conf.inc
new file mode 100644
index 00000000..0b2d7002
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/50_local.conf.inc
@@ -0,0 +1,3 @@
+
+IMAGE_INSTALL_append = " packagegroup-agl-profile-graphical-html5"
+
diff --git a/meta-agl-devel/templates/feature/agl-profile-graphical-html5/README_feature_agl-profile-graphical-html5.md b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/README_feature_agl-profile-graphical-html5.md
new file mode 100644
index 00000000..dc00f94c
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/README_feature_agl-profile-graphical-html5.md
@@ -0,0 +1,8 @@
+---
+description: Feature agl-profile-graphical-html5
+authors: Jacobo Aragunde Pérez <jaragunde@igalia.com>
+---
+
+### Feature agl-profile-graphical-html5
+
+Packages required to run web applications in AGL. The provided image agl-image-graphical-html5 includes the minimum set of packages required for this purpose.
diff --git a/meta-agl-devel/templates/feature/agl-profile-graphical-html5/included.dep b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/included.dep
new file mode 100644
index 00000000..032609b8
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-profile-graphical-html5/included.dep
@@ -0,0 +1 @@
+agl-profile-graphical
diff --git a/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_bblayers.conf.inc b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_bblayers.conf.inc
new file mode 100644
index 00000000..31f4dca8
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_bblayers.conf.inc
@@ -0,0 +1,6 @@
+BBLAYERS =+ " \
+ ${METADIR}/external/alexa-auto-sdk/extensions/extras/amazonlite/meta-aac-amazonlite \
+"
+
+# Include the recipe for the required module as well
+BBFILES += "${METADIR}/external/alexa-auto-sdk/extensions/extras/amazonlite/modules/*/*.bb"
diff --git a/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_local.conf.inc b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_local.conf.inc
new file mode 100644
index 00000000..41af3db8
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/50_local.conf.inc
@@ -0,0 +1 @@
+ALEXA_WAKEWORD = "true"
diff --git a/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/README_feature_agl-voiceagent-alexa-wakeword.md b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/README_feature_agl-voiceagent-alexa-wakeword.md
new file mode 100644
index 00000000..e8491289
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/README_feature_agl-voiceagent-alexa-wakeword.md
@@ -0,0 +1,10 @@
+---
+description: Feature agl-voiceagent-alexa-wakeword
+authors: Scott Murray <scott.murray@konsulko.com>
+---
+
+### Feature agl-voiceagent-alexa-wakeword
+
+Enables building the Amazon Alexa voiceagent binding with included wakeword engine support.
+
+Note that this features assumes that the amazonlite wakeword engine ZIP file (e.g. amazonlite-2.0.zip) containing the required additional files has been decompressed to external/alexa-auto-sdk/extensions/extras/amazonlite in the tree. Without this, attempting to build with bitbake will fail. Please contact your Amazon Alexa developer account representative if you wish to obtain the wakeword engine.
diff --git a/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/included.dep b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/included.dep
new file mode 100644
index 00000000..71688dda
--- /dev/null
+++ b/meta-agl-devel/templates/feature/agl-voiceagent-alexa-wakeword/included.dep
@@ -0,0 +1 @@
+agl-voiceagent-alexa