diff --git a/test/browser_common.py b/test/browser_common.py index 8d15aa1e295b6..833e4a86981f5 100644 --- a/test/browser_common.py +++ b/test/browser_common.py @@ -205,6 +205,21 @@ def find_system_firefox_platform_ini(): return version +@memoize +def get_chrome_version(): + if not is_chrome(): + return UNSUPPORTED + exe = shlex.split(EMTEST_BROWSER, posix=not WINDOWS)[0] + if WINDOWS: + cmd = ['powershell', '-NoProfile', '-Command', f'(Get-Item "{exe}").VersionInfo.ProductVersion'] + else: + if exe.endswith('.app'): + exe = os.path.join(exe, 'Contents/MacOS/Google Chrome') + cmd = [exe, '--version'] + version = subprocess.check_output(cmd, text=True) + return int(re.search(r'\b(\d+)\.', version).group(1)) + + def browser_should_skip_feature(skip_env_var, feature): # If an env. var. EMTEST_LACKS_x to skip the given test is set (to either # value 0 or 1), don't bother checking if current browser supports the feature @@ -243,6 +258,7 @@ class ChromeConfig: # this flag for now: https://crbug.com/638180 '--no-first-run -start-maximized --no-sandbox --enable-unsafe-swiftshader --use-gl=swiftshader --enable-features=JavaScriptSourcePhaseImports', '--enable-experimental-webassembly-features', + '--enable-blink-features=AudioWorkletSharedPort', # The runners lack sound hardware so fallback to a dummy device (and # bypass the user gesture so audio tests work without interaction) '--use-fake-device-for-media-stream --autoplay-policy=no-user-gesture-required', diff --git a/test/test_browser.py b/test/test_browser.py index ce35e41905e63..15f8629956415 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -31,6 +31,7 @@ browser_should_skip_feature, find_browser_test_file, get_browser, + get_chrome_version, get_firefox_version, get_safari_version, is_chrome, @@ -181,6 +182,7 @@ def decorator(min_required_version, note=''): requires_safari_version = requires_version('safari', get_safari_version) requires_firefox_version = requires_version('firefox', get_firefox_version) +requires_chrome_version = requires_version('chrome', get_chrome_version) def is_jspi(args): @@ -5434,6 +5436,15 @@ def test_audio_worklet(self, args): self.skipTest('This test requires a browser with ES6 Module Workers support') self.btest_exit('webaudio/audioworklet.c', cflags=['-sAUDIO_WORKLET', '-sWASM_WORKERS', '-DTEST_AND_EXIT'] + args) + # Tests that AudioWorklet.port (spec-defined shared MessagePort) can be used + # without falling back to the em-bootstrap AudioWorkletProcessor. + @requires_sound_hardware + @no_safari('https://bugs.webkit.org/show_bug.cgi?id=299386') + @requires_firefox_version(138) + @requires_chrome_version(155, 'https://crbug.com/40210558') + def test_audio_worklet_port(self): + self.btest_exit('webaudio/test_audio_worklet_port.c', cflags=['-sAUDIO_WORKLET', '-sWASM_WORKERS']) + # Tests that audioworklets and workers can be used at the same time # Note: doesn't need audio hardware (and has no AW code that tests 2GB or wasm64) def test_audio_worklet_worker(self): diff --git a/test/webaudio/test_audio_worklet_port.c b/test/webaudio/test_audio_worklet_port.c new file mode 100644 index 0000000000000..d35dc2ee8147e --- /dev/null +++ b/test/webaudio/test_audio_worklet_port.c @@ -0,0 +1,33 @@ +#include +#include +#include + +uint8_t audio_worklet_stack[4096]; +EMSCRIPTEN_WEBAUDIO_T audio_context; + +void do_exit() { + emscripten_destroy_audio_context(audio_context); + emscripten_force_exit(0); +} + +void in_audio_worklet() { + assert(emscripten_current_thread_is_audio_worklet()); + emscripten_audio_worklet_post_function_v(EMSCRIPTEN_AUDIO_MAIN_THREAD, do_exit); +} + +void worklet_init(EMSCRIPTEN_WEBAUDIO_T ctx, bool success, void* userData) { + assert(success); + EM_ASM({ + var audio = emscriptenGetAudioObject($0); + assert(audio.audioWorklet.port instanceof MessagePort); + assert(!audio.audioWorklet.bootstrapMessage); + }, ctx); + emscripten_audio_worklet_post_function_v(ctx, in_audio_worklet); +} + +int main() { + audio_context = emscripten_create_audio_context(0); + emscripten_start_wasm_audio_worklet_thread_async( + audio_context, audio_worklet_stack, sizeof(audio_worklet_stack), worklet_init, 0); + emscripten_exit_with_live_runtime(); +}