From dc67863cbcab95476120bf2ebf9116385a46ee50 Mon Sep 17 00:00:00 2001 From: Valere Fedronic Date: Thu, 4 Dec 2025 15:59:48 +0100 Subject: [PATCH] call: Pass the echo cancellation and noise suppression settings to EC (#31317) --- src/models/Call.ts | 11 ++++ test/unit-tests/models/Call-test.ts | 90 +++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/models/Call.ts b/src/models/Call.ts index 1882eec964..ebf3f7b50a 100644 --- a/src/models/Call.ts +++ b/src/models/Call.ts @@ -744,6 +744,17 @@ export class ElementCall extends Call { params.append("allowIceFallback", "true"); } + const echoCancellation = SettingsStore.getValue("webrtc_audio_echoCancellation"); + if (!echoCancellation) { + // the default is true, so only set if false + params.append("echoCancellation", "false"); + } + const noiseSuppression = SettingsStore.getValue("webrtc_audio_noiseSuppression"); + if (!noiseSuppression) { + // the default is true, so only set if false + params.append("noiseSuppression", "false"); + } + // Set custom fonts if (SettingsStore.getValue("useSystemFont")) { SettingsStore.getValue("systemFont") diff --git a/test/unit-tests/models/Call-test.ts b/test/unit-tests/models/Call-test.ts index dbf2dca974..9e2233d759 100644 --- a/test/unit-tests/models/Call-test.ts +++ b/test/unit-tests/models/Call-test.ts @@ -567,6 +567,96 @@ describe("ElementCall", () => { SettingsStore.getValue = originalGetValue; }); + describe("Echo cancellation & Noise Suppression", () => { + it("passes echo cancellation settings through widget URL if needed", async () => { + const originalGetValue = SettingsStore.getValue; + SettingsStore.getValue = ( + name: SettingKey, + roomId: string | null = null, + excludeDefault = false, + ): any => { + switch (name) { + case "webrtc_audio_echoCancellation": + return false; + } + }; + ElementCall.create(room); + const call = Call.get(room); + if (!(call instanceof ElementCall)) throw new Error("Failed to create call"); + + const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); + expect(urlParams.get("echoCancellation")).toBe("false"); + + SettingsStore.getValue = originalGetValue; + }); + + it("does not pass echo cancellation settings through widget URL if not needed", async () => { + const originalGetValue = SettingsStore.getValue; + SettingsStore.getValue = ( + name: SettingKey, + roomId: string | null = null, + excludeDefault = false, + ): any => { + switch (name) { + case "webrtc_audio_echoCancellation": + return true; + } + }; + ElementCall.create(room); + const call = Call.get(room); + if (!(call instanceof ElementCall)) throw new Error("Failed to create call"); + + const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); + expect(urlParams.get("echoCancellation")).toBeNull(); + + SettingsStore.getValue = originalGetValue; + }); + + it("passes noise suppression settings through widget URL if needed", async () => { + const originalGetValue = SettingsStore.getValue; + SettingsStore.getValue = ( + name: SettingKey, + roomId: string | null = null, + excludeDefault = false, + ): any => { + switch (name) { + case "webrtc_audio_noiseSuppression": + return false; + } + }; + ElementCall.create(room); + const call = Call.get(room); + if (!(call instanceof ElementCall)) throw new Error("Failed to create call"); + + const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); + expect(urlParams.get("noiseSuppression")).toBe("false"); + + SettingsStore.getValue = originalGetValue; + }); + + it("does not pass noise suppression settings through widget URL if not needed", async () => { + const originalGetValue = SettingsStore.getValue; + SettingsStore.getValue = ( + name: SettingKey, + roomId: string | null = null, + excludeDefault = false, + ): any => { + switch (name) { + case "webrtc_audio_noiseSuppression": + return true; + } + }; + ElementCall.create(room); + const call = Call.get(room); + if (!(call instanceof ElementCall)) throw new Error("Failed to create call"); + + const urlParams = new URLSearchParams(new URL(call.widget.url).hash.slice(1)); + expect(urlParams.get("noiseSuppression")).toBeNull(); + + SettingsStore.getValue = originalGetValue; + }); + }); + it("passes ICE fallback preference through widget URL", async () => { // Test with the preference set to false ElementCall.create(room);