diff --git a/webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp b/webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp index 63f15b0b..4e87abcd 100644 --- a/webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp +++ b/webrtc-jni/src/main/cpp/src/JNI_PeerConnectionFactory.cpp @@ -28,7 +28,9 @@ #include "JavaRef.h" #include "JavaString.h" #include "JavaUtils.h" +#include "WebRTCContext.h" +#include "api/audio/create_audio_device_module.h" #include "api/create_peerconnection_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h" @@ -89,6 +91,25 @@ JNIEXPORT void JNICALL Java_dev_onvoid_webrtc_PeerConnectionFactory_initialize webrtc::scoped_refptr apm(processing); webrtc::scoped_refptr adm(audioDevModule); + if (!adm) { + // Without a module, the factory would create the platform default itself + // and abort the process when it fails to initialize, which happens on + // hosts without an audio system. Create it here instead, the same way + // AudioDeviceModule does, so a failure becomes an exception that the + // application can handle, for example by passing a module created + // with AudioLayer.kDummyAudio. + jni::WebRTCContext * context = static_cast(javaContext); + + adm = webrtc::CreateAudioDeviceModule(context->webrtcEnv, webrtc::AudioDeviceModule::kPlatformDefaultAudio); + + if (!adm) { + throw jni::Exception("Create the default AudioDeviceModule failed"); + } + if (adm->Init() != 0) { + throw jni::Exception("Initialize the default AudioDeviceModule failed. On a host without an audio system, pass an AudioDeviceModule created with AudioLayer.kDummyAudio."); + } + } + auto factory = webrtc::CreatePeerConnectionFactory( networkThread.get(), workerThread.get(), diff --git a/webrtc/src/test/java/dev/onvoid/webrtc/PeerConnectionFactoryTests.java b/webrtc/src/test/java/dev/onvoid/webrtc/PeerConnectionFactoryTests.java index 53872b50..8f78711e 100644 --- a/webrtc/src/test/java/dev/onvoid/webrtc/PeerConnectionFactoryTests.java +++ b/webrtc/src/test/java/dev/onvoid/webrtc/PeerConnectionFactoryTests.java @@ -29,6 +29,20 @@ class PeerConnectionFactoryTests extends TestBase { + @Test + void createWithoutAudioDeviceModule() { + // Without a module the factory creates the platform default. On a host + // without an audio system that must fail with an exception, not abort + // the process. + try { + PeerConnectionFactory factory = new PeerConnectionFactory(); + factory.dispose(); + } + catch (Error e) { + assertTrue(e.getMessage().contains("AudioDeviceModule"), e.getMessage()); + } + } + @Test void createWithAudioDeviceModule() { AudioDeviceModule audioDevModule = new AudioDeviceModule(AudioLayer.kDummyAudio);