Create PeerConnection specific environment

Bug: webrtc:15656
Change-Id: I11616e3470798b43cb07a776f5d58669d629e24d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328960
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41283}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 8c85788..e73213f 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -1236,6 +1236,7 @@
     "../api:turn_customizer",
     "../api/adaptation:resource_adaptation_api",
     "../api/crypto:options",
+    "../api/environment",
     "../api/rtc_event_log",
     "../api/task_queue:pending_task_safety_flag",
     "../api/transport:bitrate_settings",
diff --git a/pc/connection_context.h b/pc/connection_context.h
index 148a9cb..e66df9f 100644
--- a/pc/connection_context.h
+++ b/pc/connection_context.h
@@ -76,6 +76,11 @@
   rtc::Thread* network_thread() { return network_thread_; }
   const rtc::Thread* network_thread() const { return network_thread_; }
 
+  // Environment associated with the PeerConnectionFactory.
+  // Note: environments are different for different PeerConnections,
+  // but they are not supposed to change after creating the PeerConnection.
+  const Environment& env() const { return env_; }
+
   // Field trials associated with the PeerConnectionFactory.
   // Note: that there can be different field trials for different
   // PeerConnections (but they are not supposed change after creating the
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 611d5b4..8bbffa3 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -23,6 +23,7 @@
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
 #include "absl/types/optional.h"
+#include "api/environment/environment.h"
 #include "api/jsep_ice_candidate.h"
 #include "api/media_types.h"
 #include "api/rtp_parameters.h"
@@ -536,9 +537,9 @@
 }
 
 RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
+    const Environment& env,
     rtc::scoped_refptr<ConnectionContext> context,
     const PeerConnectionFactoryInterface::Options& options,
-    std::unique_ptr<RtcEventLog> event_log,
     std::unique_ptr<Call> call,
     const PeerConnectionInterface::RTCConfiguration& configuration,
     PeerConnectionDependencies dependencies) {
@@ -605,8 +606,8 @@
 
   // The PeerConnection constructor consumes some, but not all, dependencies.
   auto pc = rtc::make_ref_counted<PeerConnection>(
-      context, options, is_unified_plan, std::move(event_log), std::move(call),
-      dependencies, dtls_enabled);
+      env, context, options, is_unified_plan, std::move(call), dependencies,
+      dtls_enabled);
   RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
   if (!init_error.ok()) {
     RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
@@ -616,19 +617,18 @@
 }
 
 PeerConnection::PeerConnection(
+    const Environment& env,
     rtc::scoped_refptr<ConnectionContext> context,
     const PeerConnectionFactoryInterface::Options& options,
     bool is_unified_plan,
-    std::unique_ptr<RtcEventLog> event_log,
     std::unique_ptr<Call> call,
     PeerConnectionDependencies& dependencies,
     bool dtls_enabled)
-    : context_(context),
-      trials_(std::move(dependencies.trials), &context->field_trials()),
+    : env_(env),
+      context_(context),
       options_(options),
       observer_(dependencies.observer),
       is_unified_plan_(is_unified_plan),
-      event_log_(std::move(event_log)),
       async_dns_resolver_factory_(
           std::move(dependencies.async_dns_resolver_factory)),
       port_allocator_(std::move(dependencies.allocator)),
@@ -648,7 +648,8 @@
       data_channel_controller_(this),
       message_handler_(signaling_thread()),
       weak_factory_(this) {
-  RTC_CHECK(event_log_);
+  // Field trials specific to the peerconnection should be owned by the `env`,
+  RTC_DCHECK(dependencies.trials == nullptr);
 }
 
 PeerConnection::~PeerConnection() {
@@ -796,7 +797,7 @@
   config.transport_observer = this;
   config.rtcp_handler = InitializeRtcpCallback();
   config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler();
-  config.event_log = event_log_.get();
+  config.event_log = &env_.event_log();
 #if defined(ENABLE_EXTERNAL_AUTH)
   config.enable_external_auth = true;
 #endif
@@ -815,7 +816,7 @@
         }
       };
 
-  config.field_trials = trials_.get();
+  config.field_trials = &env_.field_trials();
 
   transport_controller_.reset(new JsepTransportController(
       network_thread(), port_allocator_.get(),
@@ -2256,12 +2257,12 @@
   if (!worker_thread_safety_->alive()) {
     return false;
   }
-  return event_log_->StartLogging(std::move(output), output_period_ms);
+  return env_.event_log().StartLogging(std::move(output), output_period_ms);
 }
 
 void PeerConnection::StopRtcEventLog_w() {
   RTC_DCHECK_RUN_ON(worker_thread());
-  event_log_->StopLogging();
+  env_.event_log().StopLogging();
 }
 
 absl::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index b916265..e6037a2 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -27,6 +27,7 @@
 #include "api/crypto/crypto_options.h"
 #include "api/data_channel_interface.h"
 #include "api/dtls_transport_interface.h"
+#include "api/environment/environment.h"
 #include "api/field_trials_view.h"
 #include "api/ice_transport_interface.h"
 #include "api/jsep.h"
@@ -110,9 +111,9 @@
   // Note that the function takes ownership of dependencies, and will
   // either use them or release them, whether it succeeds or fails.
   static RTCErrorOr<rtc::scoped_refptr<PeerConnection>> Create(
+      const Environment& env,
       rtc::scoped_refptr<ConnectionContext> context,
       const PeerConnectionFactoryInterface::Options& options,
-      std::unique_ptr<RtcEventLog> event_log,
       std::unique_ptr<Call> call,
       const PeerConnectionInterface::RTCConfiguration& configuration,
       PeerConnectionDependencies dependencies);
@@ -428,7 +429,7 @@
   void TeardownDataChannelTransport_n(RTCError error)
       RTC_RUN_ON(network_thread());
 
-  const FieldTrialsView& trials() const override { return *trials_; }
+  const FieldTrialsView& trials() const override { return env_.field_trials(); }
 
   bool ConfiguredForMedia() const;
 
@@ -441,10 +442,10 @@
 
  protected:
   // Available for rtc::scoped_refptr creation
-  PeerConnection(rtc::scoped_refptr<ConnectionContext> context,
+  PeerConnection(const Environment& env,
+                 rtc::scoped_refptr<ConnectionContext> context,
                  const PeerConnectionFactoryInterface::Options& options,
                  bool is_unified_plan,
-                 std::unique_ptr<RtcEventLog> event_log,
                  std::unique_ptr<Call> call,
                  PeerConnectionDependencies& dependencies,
                  bool dtls_enabled);
@@ -597,23 +598,14 @@
   std::function<void(const RtpPacketReceived& parsed_packet)>
   InitializeUnDemuxablePacketHandler();
 
+  const Environment env_;
   const rtc::scoped_refptr<ConnectionContext> context_;
-  // Field trials active for this PeerConnection is the first of:
-  // a) Specified in PeerConnectionDependencies (owned).
-  // b) Accessed via ConnectionContext (e.g PeerConnectionFactoryDependencies>
-  // c) Created as Default (FieldTrialBasedConfig).
-  const AlwaysValidPointer<const FieldTrialsView, FieldTrialBasedConfig>
-      trials_;
   const PeerConnectionFactoryInterface::Options options_;
   PeerConnectionObserver* observer_ RTC_GUARDED_BY(signaling_thread()) =
       nullptr;
 
   const bool is_unified_plan_;
 
-  // The EventLog needs to outlive `call_` (and any other object that uses it).
-  const std::unique_ptr<RtcEventLog> event_log_
-      RTC_PT_GUARDED_BY(worker_thread());
-
   IceConnectionState ice_connection_state_ RTC_GUARDED_BY(signaling_thread()) =
       kIceConnectionNew;
   PeerConnectionInterface::IceConnectionState standardized_ice_connection_state_
diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc
index 441c809..ab0bc24 100644
--- a/pc/peer_connection_factory.cc
+++ b/pc/peer_connection_factory.cc
@@ -220,6 +220,23 @@
     PeerConnectionDependencies dependencies) {
   RTC_DCHECK_RUN_ON(signaling_thread());
 
+  EnvironmentFactory env_factory(context_->env());
+
+  // Field trials active for this PeerConnection is the first of:
+  // a) Specified in the PeerConnectionDependencies
+  // b) Specified in the PeerConnectionFactoryDependencies
+  // c) Created as default by the EnvironmentFactory.
+  env_factory.Set(std::move(dependencies.trials));
+
+  if (event_log_factory_ != nullptr) {
+    worker_thread()->BlockingCall([&] {
+      Environment env_for_rtc_event_log = env_factory.Create();
+      env_factory.Set(event_log_factory_->Create(env_for_rtc_event_log));
+    });
+  }
+
+  const Environment env = env_factory.Create();
+
   // Set internal defaults if optional dependencies are not set.
   if (!dependencies.cert_generator) {
     dependencies.cert_generator =
@@ -227,11 +244,10 @@
                                                        network_thread());
   }
   if (!dependencies.allocator) {
-    const FieldTrialsView* trials =
-        dependencies.trials ? dependencies.trials.get() : &field_trials();
     dependencies.allocator = std::make_unique<cricket::BasicPortAllocator>(
         context_->default_network_manager(), context_->default_socket_factory(),
-        configuration.turn_customizer, /*relay_port_factory=*/nullptr, trials);
+        configuration.turn_customizer, /*relay_port_factory=*/nullptr,
+        &env.field_trials());
     dependencies.allocator->SetPortRange(
         configuration.port_allocator_config.min_port,
         configuration.port_allocator_config.max_port);
@@ -247,19 +263,13 @@
   dependencies.allocator->SetNetworkIgnoreMask(options().network_ignore_mask);
   dependencies.allocator->SetVpnList(configuration.vpn_list);
 
-  std::unique_ptr<RtcEventLog> event_log =
-      worker_thread()->BlockingCall([this] { return CreateRtcEventLog_w(); });
-
-  const FieldTrialsView* trials =
-      dependencies.trials ? dependencies.trials.get() : &field_trials();
   std::unique_ptr<Call> call =
-      worker_thread()->BlockingCall([this, &event_log, trials, &configuration] {
-        return CreateCall_w(event_log.get(), *trials, configuration);
+      worker_thread()->BlockingCall([this, &env, &configuration] {
+        return CreateCall_w(env, configuration);
       });
 
-  auto result = PeerConnection::Create(context_, options_, std::move(event_log),
-                                       std::move(call), configuration,
-                                       std::move(dependencies));
+  auto result = PeerConnection::Create(env, context_, options_, std::move(call),
+                                       configuration, std::move(dependencies));
   if (!result.ok()) {
     return result.MoveError();
   }
@@ -300,23 +310,12 @@
   return AudioTrackProxy::Create(signaling_thread(), track);
 }
 
-std::unique_ptr<RtcEventLog> PeerConnectionFactory::CreateRtcEventLog_w() {
-  RTC_DCHECK_RUN_ON(worker_thread());
-
-  auto encoding_type = RtcEventLog::EncodingType::NewFormat;
-  if (field_trials().IsDisabled("WebRTC-RtcEventLogNewFormat"))
-    encoding_type = RtcEventLog::EncodingType::Legacy;
-  return event_log_factory_ ? event_log_factory_->Create(encoding_type)
-                            : std::make_unique<RtcEventLogNull>();
-}
-
 std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
-    RtcEventLog* event_log,
-    const FieldTrialsView& field_trials,
+    const Environment& env,
     const PeerConnectionInterface::RTCConfiguration& configuration) {
   RTC_DCHECK_RUN_ON(worker_thread());
 
-  CallConfig call_config(event_log, network_thread());
+  CallConfig call_config(env, network_thread());
   if (!media_engine() || !context_->call_factory()) {
     return nullptr;
   }
@@ -329,7 +328,7 @@
   FieldTrialParameter<DataRate> max_bandwidth("max",
                                               DataRate::KilobitsPerSec(2000));
   ParseFieldTrial({&min_bandwidth, &start_bandwidth, &max_bandwidth},
-                  field_trials.Lookup("WebRTC-PcFactoryDefaultBitrates"));
+                  env.field_trials().Lookup("WebRTC-PcFactoryDefaultBitrates"));
 
   call_config.bitrate_config.min_bitrate_bps =
       rtc::saturated_cast<int>(min_bandwidth->bps());
@@ -339,7 +338,6 @@
       rtc::saturated_cast<int>(max_bandwidth->bps());
 
   call_config.fec_controller_factory = fec_controller_factory_.get();
-  call_config.task_queue_factory = task_queue_factory_.get();
   call_config.network_state_predictor_factory =
       network_state_predictor_factory_.get();
   call_config.neteq_factory = neteq_factory_.get();
@@ -352,7 +350,6 @@
     RTC_LOG(LS_INFO) << "Using default network controller factory";
   }
 
-  call_config.trials = &field_trials;
   call_config.rtp_transport_controller_send_factory =
       transport_controller_send_factory_.get();
   call_config.metronome = metronome_.get();
diff --git a/pc/peer_connection_factory.h b/pc/peer_connection_factory.h
index f55d09f..5e652a7 100644
--- a/pc/peer_connection_factory.h
+++ b/pc/peer_connection_factory.h
@@ -29,7 +29,6 @@
 #include "api/network_state_predictor.h"
 #include "api/peer_connection_interface.h"
 #include "api/rtc_error.h"
-#include "api/rtc_event_log/rtc_event_log.h"
 #include "api/rtc_event_log/rtc_event_log_factory_interface.h"
 #include "api/rtp_parameters.h"
 #include "api/scoped_refptr.h"
@@ -53,8 +52,6 @@
 
 namespace webrtc {
 
-class RtcEventLog;
-
 class PeerConnectionFactory : public PeerConnectionFactoryInterface {
  public:
   // Creates a PeerConnectionFactory. It returns nullptr on initialization
@@ -135,10 +132,8 @@
 
   bool IsTrialEnabled(absl::string_view key) const;
 
-  std::unique_ptr<RtcEventLog> CreateRtcEventLog_w();
   std::unique_ptr<Call> CreateCall_w(
-      RtcEventLog* event_log,
-      const FieldTrialsView& field_trials,
+      const Environment& env,
       const PeerConnectionInterface::RTCConfiguration& configuration);
 
   rtc::scoped_refptr<ConnectionContext> context_;