Allow to provide prebuild Environment to construct PeerConnectionFactory
That would allow to share the Environment across PeerConnectionFactory
and its injected dependencies, e.g. AudioDeviceModuel
Bug: webrtc:413413572
Change-Id: Ic99a2e39664e224a3d63e73ba8e584cbee838bfd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/388140
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Owners-Override: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#44473}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 7a35918..6340d2b 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -366,6 +366,7 @@
"crypto:frame_decryptor_interface",
"crypto:frame_encryptor_interface",
"crypto:options",
+ "environment",
"metronome",
"neteq:neteq_api",
"rtc_event_log:rtc_event_log_factory_interface",
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index de071d5..bffbf07 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -92,6 +92,7 @@
#include "api/data_channel_event_observer_interface.h"
#include "api/data_channel_interface.h"
#include "api/dtls_transport_interface.h"
+#include "api/environment/environment.h"
#include "api/fec_controller.h"
#include "api/field_trials_view.h"
#include "api/ice_transport_interface.h"
@@ -1430,9 +1431,18 @@
Thread* worker_thread = nullptr;
Thread* signaling_thread = nullptr;
SocketFactory* socket_factory = nullptr;
+
+ // Provides common widely used dependencies for webrtc subcomponents.
+ // `task_queue_factory` and `field_trials` members below override values in
+ // `env` when set.
+ std::optional<Environment> env;
+
// The `packet_socket_factory` will only be used if CreatePeerConnection is
// called without a `port_allocator`.
std::unique_ptr<PacketSocketFactory> packet_socket_factory;
+ // Deprecated. Instead provide custom task queue factory through the `env`.
+ // TODO: bugs.webrtc.org/42220378 - Mark [[deprecated]] once unused in WebRTC
+ // and chromium
std::unique_ptr<TaskQueueFactory> task_queue_factory;
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
@@ -1448,6 +1458,9 @@
std::unique_ptr<NetworkMonitorFactory> network_monitor_factory;
std::unique_ptr<NetEqFactory> neteq_factory;
std::unique_ptr<SctpTransportFactoryInterface> sctp_factory;
+ // Deprecated. Instead provide custom field trials through the `env`.
+ // TODO: bugs.webrtc.org/42220378 - Mark [[deprecated]] once unused in WebRTC
+ // and chromium
std::unique_ptr<FieldTrialsView> trials;
std::unique_ptr<RtpTransportControllerSendFactoryInterface>
transport_controller_send_factory;
diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc
index e62d25a..d23aec1 100644
--- a/pc/peer_connection_factory.cc
+++ b/pc/peer_connection_factory.cc
@@ -13,6 +13,7 @@
#include <cstdint>
#include <cstdio>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -67,6 +68,25 @@
#include "rtc_base/system/file_wrapper.h"
namespace webrtc {
+namespace {
+
+Environment AssembleEnvironment(PeerConnectionFactoryDependencies& deps) {
+ // Assemble Environment here rather than in ConnectionContext::Create
+ // to avoid dependency on EnvironmentFactory by ConnectionContext and thus its
+ // users.
+ EnvironmentFactory env_factory = deps.env.has_value()
+ ? EnvironmentFactory(*deps.env)
+ : EnvironmentFactory();
+ env_factory.Set(std::move(deps.trials));
+ env_factory.Set(std::move(deps.task_queue_factory));
+
+ // Clear Environment from `deps` to avoid accidental usage of the wrong
+ // Environment.
+ deps.env = std::nullopt;
+ return env_factory.Create();
+}
+
+} // namespace
scoped_refptr<PeerConnectionFactoryInterface>
CreateModularPeerConnectionFactory(
@@ -93,10 +113,8 @@
// Static
scoped_refptr<PeerConnectionFactory> PeerConnectionFactory::Create(
PeerConnectionFactoryDependencies dependencies) {
- auto context = ConnectionContext::Create(
- CreateEnvironment(std::move(dependencies.trials),
- std::move(dependencies.task_queue_factory)),
- &dependencies);
+ auto context = ConnectionContext::Create(AssembleEnvironment(dependencies),
+ &dependencies);
if (!context) {
return nullptr;
}
@@ -128,10 +146,8 @@
PeerConnectionFactory::PeerConnectionFactory(
PeerConnectionFactoryDependencies dependencies)
: PeerConnectionFactory(
- ConnectionContext::Create(
- CreateEnvironment(std::move(dependencies.trials),
- std::move(dependencies.task_queue_factory)),
- &dependencies),
+ ConnectionContext::Create(AssembleEnvironment(dependencies),
+ &dependencies),
&dependencies) {}
PeerConnectionFactory::~PeerConnectionFactory() {
diff --git a/pc/peer_connection_factory_unittest.cc b/pc/peer_connection_factory_unittest.cc
index f895496..aeb7987 100644
--- a/pc/peer_connection_factory_unittest.cc
+++ b/pc/peer_connection_factory_unittest.cc
@@ -25,6 +25,8 @@
#include "api/enable_media.h"
#include "api/enable_media_with_defaults.h"
#include "api/environment/environment_factory.h"
+#include "api/field_trials.h"
+#include "api/field_trials_view.h"
#include "api/jsep.h"
#include "api/make_ref_counted.h"
#include "api/media_stream_interface.h"
@@ -32,7 +34,6 @@
#include "api/peer_connection_interface.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
-#include "api/task_queue/default_task_queue_factory.h"
#include "api/test/mock_packet_socket_factory.h"
#include "api/units/time_delta.h"
#include "api/video_codecs/scalability_mode.h"
@@ -80,6 +81,7 @@
using ::testing::AtLeast;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
+using ::testing::NotNull;
using ::testing::Return;
using ::testing::UnorderedElementsAre;
using ::webrtc::test::MockAudioProcessing;
@@ -275,7 +277,6 @@
pcf_dependencies.signaling_thread = Thread::Current();
pcf_dependencies.worker_thread = Thread::Current();
pcf_dependencies.network_thread = Thread::Current();
- pcf_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
pcf_dependencies.adm = FakeAudioCaptureModule::Create();
pcf_dependencies.audio_encoder_factory = CreateBuiltinAudioEncoderFactory();
@@ -662,6 +663,43 @@
EXPECT_FALSE(local_renderer.black_frame());
}
+TEST(PeerConnectionFactoryDependenciesTest,
+ CanInjectFieldTrialsWithEnvironment) {
+ std::unique_ptr<FieldTrialsView> field_trials =
+ FieldTrials::CreateNoGlobal("");
+ ASSERT_THAT(field_trials, NotNull());
+ FieldTrialsView* raw_field_trials = field_trials.get();
+
+ PeerConnectionFactoryDependencies pcf_dependencies;
+ pcf_dependencies.env = CreateEnvironment(std::move(field_trials));
+ pcf_dependencies.adm = FakeAudioCaptureModule::Create();
+ EnableMediaWithDefaults(pcf_dependencies);
+
+ scoped_refptr<PeerConnectionFactory> pcf =
+ PeerConnectionFactory::Create(std::move(pcf_dependencies));
+ EXPECT_EQ(&pcf->field_trials(), raw_field_trials);
+}
+
+TEST(PeerConnectionFactoryDependenciesTest,
+ PreferFieldTrialsInjectedExplicetly) {
+ std::unique_ptr<FieldTrialsView> env_field_trials =
+ FieldTrials::CreateNoGlobal("");
+ std::unique_ptr<FieldTrialsView> explicit_field_trials =
+ FieldTrials::CreateNoGlobal("");
+ ASSERT_FALSE(env_field_trials.get() == explicit_field_trials.get());
+ FieldTrialsView* raw_explicit_field_trials = explicit_field_trials.get();
+
+ PeerConnectionFactoryDependencies pcf_dependencies;
+ pcf_dependencies.env = CreateEnvironment(std::move(env_field_trials));
+ pcf_dependencies.trials = std::move(explicit_field_trials);
+ pcf_dependencies.adm = FakeAudioCaptureModule::Create();
+ EnableMediaWithDefaults(pcf_dependencies);
+
+ scoped_refptr<PeerConnectionFactory> pcf =
+ PeerConnectionFactory::Create(std::move(pcf_dependencies));
+ EXPECT_EQ(&pcf->field_trials(), raw_explicit_field_trials);
+}
+
TEST(PeerConnectionFactoryDependenciesTest, UsesNetworkManager) {
constexpr TimeDelta kWaitTimeout = TimeDelta::Seconds(10);
auto mock_network_manager = std::make_unique<NiceMock<MockNetworkManager>>();
diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h
index 0873408..b11aadb 100644
--- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h
+++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Native.h
@@ -34,7 +34,7 @@
/* Initialize object with provided dependencies and with media support. */
- (instancetype)initWithMediaAndDependencies:
- (webrtc::PeerConnectionFactoryDependencies)dependencies;
+ (webrtc::PeerConnectionFactoryDependencies &)dependencies;
/* Initialize object with injectable native audio/video encoder/decoder
* factories */
diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm
index 79afe27..81eafe6 100644
--- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm
+++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm
@@ -81,7 +81,7 @@
dependencies.video_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(
[[RTC_OBJC_TYPE(RTCVideoDecoderFactoryH264) alloc] init]);
dependencies.adm = [self audioDeviceModule];
- return [self initWithMediaAndDependencies:std::move(dependencies)];
+ return [self initWithMediaAndDependencies:dependencies];
}
- (instancetype)
@@ -122,12 +122,12 @@
} else {
dependencies.adm = [self audioDeviceModule];
}
- return [self initWithMediaAndDependencies:std::move(dependencies)];
+ return [self initWithMediaAndDependencies:dependencies];
#endif
}
- (instancetype)initWithNativeDependencies:
- (webrtc::PeerConnectionFactoryDependencies)dependencies {
+ (webrtc::PeerConnectionFactoryDependencies &)dependencies {
self = [super init];
if (self) {
_networkThread = webrtc::Thread::CreateWithSocketServer();
@@ -167,8 +167,8 @@
}
- (instancetype)initWithNoMedia {
- return [self
- initWithNativeDependencies:webrtc::PeerConnectionFactoryDependencies()];
+ webrtc::PeerConnectionFactoryDependencies default_deps;
+ return [self initWithNativeDependencies:default_deps];
}
- (instancetype)
@@ -198,7 +198,7 @@
dependencies.audio_processing_builder =
CustomAudioProcessing(std::move(audioProcessingModule));
}
- return [self initWithMediaAndDependencies:std::move(dependencies)];
+ return [self initWithMediaAndDependencies:dependencies];
}
- (instancetype)
@@ -232,11 +232,11 @@
CustomAudioProcessing(std::move(audioProcessingModule));
}
dependencies.network_controller_factory = std::move(networkControllerFactory);
- return [self initWithMediaAndDependencies:std::move(dependencies)];
+ return [self initWithMediaAndDependencies:dependencies];
}
- (instancetype)initWithMediaAndDependencies:
- (webrtc::PeerConnectionFactoryDependencies)dependencies {
+ (webrtc::PeerConnectionFactoryDependencies &)dependencies {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// audio_processing_builder should be used instead in new code.
@@ -254,7 +254,7 @@
std::make_unique<webrtc::RtcEventLogFactory>();
}
webrtc::EnableMedia(dependencies);
- return [self initWithNativeDependencies:std::move(dependencies)];
+ return [self initWithNativeDependencies:dependencies];
}
- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:
diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm b/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm
index 8fe5565..3485dc8 100644
--- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm
+++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactoryBuilder.mm
@@ -28,7 +28,7 @@
- (RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)createPeerConnectionFactory {
return [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc]
- initWithMediaAndDependencies:std::move(_dependencies)];
+ initWithMediaAndDependencies:_dependencies];
}
- (void)setFieldTrials:(std::unique_ptr<webrtc::FieldTrialsView>)fieldTrials {
diff --git a/sdk/objc/unittests/RTCPeerConnectionFactoryBuilderTest.mm b/sdk/objc/unittests/RTCPeerConnectionFactoryBuilderTest.mm
index 95d8b05..929490b 100644
--- a/sdk/objc/unittests/RTCPeerConnectionFactoryBuilderTest.mm
+++ b/sdk/objc/unittests/RTCPeerConnectionFactoryBuilderTest.mm
@@ -40,9 +40,9 @@
id factoryMock =
OCMStrictClassMock([RTC_OBJC_TYPE(RTCPeerConnectionFactory) class]);
OCMExpect([factoryMock alloc]).andReturn(factoryMock);
+ webrtc::PeerConnectionFactoryDependencies default_deps;
RTC_UNUSED([[[[factoryMock expect] andReturn:factoryMock]
- ignoringNonObjectArgs] initWithMediaAndDependencies:
- webrtc::PeerConnectionFactoryDependencies()]);
+ ignoringNonObjectArgs] initWithMediaAndDependencies:default_deps]);
RTCPeerConnectionFactoryBuilder* builder =
[[RTCPeerConnectionFactoryBuilder alloc] init];
RTC_OBJC_TYPE(RTCPeerConnectionFactory)* peerConnectionFactory =
@@ -55,9 +55,9 @@
id factoryMock =
OCMStrictClassMock([RTC_OBJC_TYPE(RTCPeerConnectionFactory) class]);
OCMExpect([factoryMock alloc]).andReturn(factoryMock);
+ webrtc::PeerConnectionFactoryDependencies default_deps;
RTC_UNUSED([[[[factoryMock expect] andReturn:factoryMock]
- ignoringNonObjectArgs] initWithMediaAndDependencies:
- webrtc::PeerConnectionFactoryDependencies()]);
+ ignoringNonObjectArgs] initWithMediaAndDependencies:default_deps]);
RTCPeerConnectionFactoryBuilder* builder =
[RTCPeerConnectionFactoryBuilder defaultBuilder];
RTC_OBJC_TYPE(RTCPeerConnectionFactory)* peerConnectionFactory =
diff --git a/tools_webrtc/iwyu/iwyu-verifier-filter_list.json b/tools_webrtc/iwyu/iwyu-verifier-filter_list.json
index 9cd95be..364d2c8 100644
--- a/tools_webrtc/iwyu/iwyu-verifier-filter_list.json
+++ b/tools_webrtc/iwyu/iwyu-verifier-filter_list.json
@@ -9,6 +9,7 @@
"modules/desktop_capture/win/",
"rtc_base/win",
"sdk/android/src/jni/",
+ "sdk/objc/",
"test/ios/",
"test/mac/"
]