1 /*
2  *  Copyright 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "pc/peer_connection.h"
12 
13 #include <limits.h>
14 #include <stddef.h>
15 #include <algorithm>
16 #include <memory>
17 #include <set>
18 #include <utility>
19 
20 #include "absl/algorithm/container.h"
21 #include "absl/strings/match.h"
22 #include "api/jsep_ice_candidate.h"
23 #include "api/rtp_parameters.h"
24 #include "api/rtp_transceiver_direction.h"
25 #include "api/task_queue/queued_task.h"
26 #include "api/transport/webrtc_key_value_config.h"
27 #include "api/uma_metrics.h"
28 #include "api/video/video_codec_constants.h"
29 #include "call/audio_state.h"
30 #include "call/packet_receiver.h"
31 #include "media/base/media_channel.h"
32 #include "media/base/media_config.h"
33 #include "media/base/rid_description.h"
34 #include "media/base/stream_params.h"
35 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
36 #include "p2p/base/connection.h"
37 #include "p2p/base/connection_info.h"
38 #include "p2p/base/dtls_transport_internal.h"
39 #include "p2p/base/p2p_constants.h"
40 #include "p2p/base/p2p_transport_channel.h"
41 #include "p2p/base/transport_info.h"
42 #include "pc/ice_server_parsing.h"
43 #include "pc/rtp_receiver.h"
44 #include "pc/rtp_sender.h"
45 #include "pc/sctp_transport.h"
46 #include "pc/simulcast_description.h"
47 #include "pc/webrtc_session_description_factory.h"
48 #include "rtc_base/bind.h"
49 #include "rtc_base/helpers.h"
50 #include "rtc_base/ip_address.h"
51 #include "rtc_base/location.h"
52 #include "rtc_base/logging.h"
53 #include "rtc_base/net_helper.h"
54 #include "rtc_base/network_constants.h"
55 #include "rtc_base/callback_list.h"
56 #include "rtc_base/socket_address.h"
57 #include "rtc_base/string_encode.h"
58 #include "rtc_base/task_utils/to_queued_task.h"
59 #include "rtc_base/trace_event.h"
60 #include "rtc_base/unique_id_generator.h"
61 #include "system_wrappers/include/metrics.h"
62 
63 using cricket::ContentInfo;
64 using cricket::ContentInfos;
65 using cricket::MediaContentDescription;
66 using cricket::MediaProtocolType;
67 using cricket::RidDescription;
68 using cricket::RidDirection;
69 using cricket::SessionDescription;
70 using cricket::SimulcastDescription;
71 using cricket::SimulcastLayer;
72 using cricket::SimulcastLayerList;
73 using cricket::StreamParams;
74 using cricket::TransportInfo;
75 
76 using cricket::LOCAL_PORT_TYPE;
77 using cricket::PRFLX_PORT_TYPE;
78 using cricket::RELAY_PORT_TYPE;
79 using cricket::STUN_PORT_TYPE;
80 
81 namespace webrtc {
82 
83 namespace {
84 
85 // UMA metric names.
86 const char kSimulcastNumberOfEncodings[] =
87     "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings";
88 
89 static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
90 
91 
ConvertIceTransportTypeToCandidateFilter(PeerConnectionInterface::IceTransportsType type)92 uint32_t ConvertIceTransportTypeToCandidateFilter(
93     PeerConnectionInterface::IceTransportsType type) {
94   switch (type) {
95     case PeerConnectionInterface::kNone:
96       return cricket::CF_NONE;
97     case PeerConnectionInterface::kRelay:
98       return cricket::CF_RELAY;
99     case PeerConnectionInterface::kNoHost:
100       return (cricket::CF_ALL & ~cricket::CF_HOST);
101     case PeerConnectionInterface::kAll:
102       return cricket::CF_ALL;
103     default:
104       RTC_NOTREACHED();
105   }
106   return cricket::CF_NONE;
107 }
108 
GetIceCandidatePairCounter(const cricket::Candidate & local,const cricket::Candidate & remote)109 IceCandidatePairType GetIceCandidatePairCounter(
110     const cricket::Candidate& local,
111     const cricket::Candidate& remote) {
112   const auto& l = local.type();
113   const auto& r = remote.type();
114   const auto& host = LOCAL_PORT_TYPE;
115   const auto& srflx = STUN_PORT_TYPE;
116   const auto& relay = RELAY_PORT_TYPE;
117   const auto& prflx = PRFLX_PORT_TYPE;
118   if (l == host && r == host) {
119     bool local_hostname =
120         !local.address().hostname().empty() && local.address().IsUnresolvedIP();
121     bool remote_hostname = !remote.address().hostname().empty() &&
122                            remote.address().IsUnresolvedIP();
123     bool local_private = IPIsPrivate(local.address().ipaddr());
124     bool remote_private = IPIsPrivate(remote.address().ipaddr());
125     if (local_hostname) {
126       if (remote_hostname) {
127         return kIceCandidatePairHostNameHostName;
128       } else if (remote_private) {
129         return kIceCandidatePairHostNameHostPrivate;
130       } else {
131         return kIceCandidatePairHostNameHostPublic;
132       }
133     } else if (local_private) {
134       if (remote_hostname) {
135         return kIceCandidatePairHostPrivateHostName;
136       } else if (remote_private) {
137         return kIceCandidatePairHostPrivateHostPrivate;
138       } else {
139         return kIceCandidatePairHostPrivateHostPublic;
140       }
141     } else {
142       if (remote_hostname) {
143         return kIceCandidatePairHostPublicHostName;
144       } else if (remote_private) {
145         return kIceCandidatePairHostPublicHostPrivate;
146       } else {
147         return kIceCandidatePairHostPublicHostPublic;
148       }
149     }
150   }
151   if (l == host && r == srflx)
152     return kIceCandidatePairHostSrflx;
153   if (l == host && r == relay)
154     return kIceCandidatePairHostRelay;
155   if (l == host && r == prflx)
156     return kIceCandidatePairHostPrflx;
157   if (l == srflx && r == host)
158     return kIceCandidatePairSrflxHost;
159   if (l == srflx && r == srflx)
160     return kIceCandidatePairSrflxSrflx;
161   if (l == srflx && r == relay)
162     return kIceCandidatePairSrflxRelay;
163   if (l == srflx && r == prflx)
164     return kIceCandidatePairSrflxPrflx;
165   if (l == relay && r == host)
166     return kIceCandidatePairRelayHost;
167   if (l == relay && r == srflx)
168     return kIceCandidatePairRelaySrflx;
169   if (l == relay && r == relay)
170     return kIceCandidatePairRelayRelay;
171   if (l == relay && r == prflx)
172     return kIceCandidatePairRelayPrflx;
173   if (l == prflx && r == host)
174     return kIceCandidatePairPrflxHost;
175   if (l == prflx && r == srflx)
176     return kIceCandidatePairPrflxSrflx;
177   if (l == prflx && r == relay)
178     return kIceCandidatePairPrflxRelay;
179   return kIceCandidatePairMax;
180 }
181 
182 
RTCConfigurationToIceConfigOptionalInt(int rtc_configuration_parameter)183 absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
184     int rtc_configuration_parameter) {
185   if (rtc_configuration_parameter ==
186       webrtc::PeerConnectionInterface::RTCConfiguration::kUndefined) {
187     return absl::nullopt;
188   }
189   return rtc_configuration_parameter;
190 }
191 
192 // Check if the changes of IceTransportsType motives an ice restart.
NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,PeerConnectionInterface::IceTransportsType current,PeerConnectionInterface::IceTransportsType modified)193 bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
194                     PeerConnectionInterface::IceTransportsType current,
195                     PeerConnectionInterface::IceTransportsType modified) {
196   if (current == modified) {
197     return false;
198   }
199 
200   if (!surface_ice_candidates_on_ice_transport_type_changed) {
201     return true;
202   }
203 
204   auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
205   auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
206 
207   // If surface_ice_candidates_on_ice_transport_type_changed is true and we
208   // extend the filter, then no ice restart is needed.
209   return (current_filter & modified_filter) != current_filter;
210 }
211 
ParseIceConfig(const PeerConnectionInterface::RTCConfiguration & config)212 cricket::IceConfig ParseIceConfig(
213     const PeerConnectionInterface::RTCConfiguration& config) {
214   cricket::ContinualGatheringPolicy gathering_policy;
215   switch (config.continual_gathering_policy) {
216     case PeerConnectionInterface::GATHER_ONCE:
217       gathering_policy = cricket::GATHER_ONCE;
218       break;
219     case PeerConnectionInterface::GATHER_CONTINUALLY:
220       gathering_policy = cricket::GATHER_CONTINUALLY;
221       break;
222     default:
223       RTC_NOTREACHED();
224       gathering_policy = cricket::GATHER_ONCE;
225   }
226 
227   cricket::IceConfig ice_config;
228   ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
229       config.ice_connection_receiving_timeout);
230   ice_config.prioritize_most_likely_candidate_pairs =
231       config.prioritize_most_likely_ice_candidate_pairs;
232   ice_config.backup_connection_ping_interval =
233       RTCConfigurationToIceConfigOptionalInt(
234           config.ice_backup_candidate_pair_ping_interval);
235   ice_config.continual_gathering_policy = gathering_policy;
236   ice_config.presume_writable_when_fully_relayed =
237       config.presume_writable_when_fully_relayed;
238   ice_config.surface_ice_candidates_on_ice_transport_type_changed =
239       config.surface_ice_candidates_on_ice_transport_type_changed;
240   ice_config.ice_check_interval_strong_connectivity =
241       config.ice_check_interval_strong_connectivity;
242   ice_config.ice_check_interval_weak_connectivity =
243       config.ice_check_interval_weak_connectivity;
244   ice_config.ice_check_min_interval = config.ice_check_min_interval;
245   ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
246   ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
247   ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
248   ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
249   ice_config.network_preference = config.network_preference;
250   return ice_config;
251 }
252 
253 // Ensures the configuration doesn't have any parameters with invalid values,
254 // or values that conflict with other parameters.
255 //
256 // Returns RTCError::OK() if there are no issues.
ValidateConfiguration(const PeerConnectionInterface::RTCConfiguration & config)257 RTCError ValidateConfiguration(
258     const PeerConnectionInterface::RTCConfiguration& config) {
259   return cricket::P2PTransportChannel::ValidateIceConfig(
260       ParseIceConfig(config));
261 }
262 
HasRtcpMuxEnabled(const cricket::ContentInfo * content)263 bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
264   return content->media_description()->rtcp_mux();
265 }
266 
267 }  // namespace
268 
operator ==(const PeerConnectionInterface::RTCConfiguration & o) const269 bool PeerConnectionInterface::RTCConfiguration::operator==(
270     const PeerConnectionInterface::RTCConfiguration& o) const {
271   // This static_assert prevents us from accidentally breaking operator==.
272   // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
273   struct stuff_being_tested_for_equality {
274     IceServers servers;
275     IceTransportsType type;
276     BundlePolicy bundle_policy;
277     RtcpMuxPolicy rtcp_mux_policy;
278     std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
279     int ice_candidate_pool_size;
280     bool disable_ipv6;
281     bool disable_ipv6_on_wifi;
282     int max_ipv6_networks;
283     bool disable_link_local_networks;
284     bool enable_rtp_data_channel;
285     absl::optional<int> screencast_min_bitrate;
286     absl::optional<bool> combined_audio_video_bwe;
287     absl::optional<bool> enable_dtls_srtp;
288     TcpCandidatePolicy tcp_candidate_policy;
289     CandidateNetworkPolicy candidate_network_policy;
290     int audio_jitter_buffer_max_packets;
291     bool audio_jitter_buffer_fast_accelerate;
292     int audio_jitter_buffer_min_delay_ms;
293     bool audio_jitter_buffer_enable_rtx_handling;
294     int ice_connection_receiving_timeout;
295     int ice_backup_candidate_pair_ping_interval;
296     ContinualGatheringPolicy continual_gathering_policy;
297     bool prioritize_most_likely_ice_candidate_pairs;
298     struct cricket::MediaConfig media_config;
299     bool prune_turn_ports;
300     PortPrunePolicy turn_port_prune_policy;
301     bool presume_writable_when_fully_relayed;
302     bool enable_ice_renomination;
303     bool redetermine_role_on_ice_restart;
304     bool surface_ice_candidates_on_ice_transport_type_changed;
305     absl::optional<int> ice_check_interval_strong_connectivity;
306     absl::optional<int> ice_check_interval_weak_connectivity;
307     absl::optional<int> ice_check_min_interval;
308     absl::optional<int> ice_unwritable_timeout;
309     absl::optional<int> ice_unwritable_min_checks;
310     absl::optional<int> ice_inactive_timeout;
311     absl::optional<int> stun_candidate_keepalive_interval;
312     webrtc::TurnCustomizer* turn_customizer;
313     SdpSemantics sdp_semantics;
314     absl::optional<rtc::AdapterType> network_preference;
315     bool active_reset_srtp_params;
316     absl::optional<CryptoOptions> crypto_options;
317     bool offer_extmap_allow_mixed;
318     std::string turn_logging_id;
319     bool enable_implicit_rollback;
320     absl::optional<bool> allow_codec_switching;
321     absl::optional<int> report_usage_pattern_delay_ms;
322   };
323   static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
324                 "Did you add something to RTCConfiguration and forget to "
325                 "update operator==?");
326   return type == o.type && servers == o.servers &&
327          bundle_policy == o.bundle_policy &&
328          rtcp_mux_policy == o.rtcp_mux_policy &&
329          tcp_candidate_policy == o.tcp_candidate_policy &&
330          candidate_network_policy == o.candidate_network_policy &&
331          audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
332          audio_jitter_buffer_fast_accelerate ==
333              o.audio_jitter_buffer_fast_accelerate &&
334          audio_jitter_buffer_min_delay_ms ==
335              o.audio_jitter_buffer_min_delay_ms &&
336          audio_jitter_buffer_enable_rtx_handling ==
337              o.audio_jitter_buffer_enable_rtx_handling &&
338          ice_connection_receiving_timeout ==
339              o.ice_connection_receiving_timeout &&
340          ice_backup_candidate_pair_ping_interval ==
341              o.ice_backup_candidate_pair_ping_interval &&
342          continual_gathering_policy == o.continual_gathering_policy &&
343          certificates == o.certificates &&
344          prioritize_most_likely_ice_candidate_pairs ==
345              o.prioritize_most_likely_ice_candidate_pairs &&
346          media_config == o.media_config && disable_ipv6 == o.disable_ipv6 &&
347          disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
348          max_ipv6_networks == o.max_ipv6_networks &&
349          disable_link_local_networks == o.disable_link_local_networks &&
350          enable_rtp_data_channel == o.enable_rtp_data_channel &&
351          screencast_min_bitrate == o.screencast_min_bitrate &&
352          combined_audio_video_bwe == o.combined_audio_video_bwe &&
353          enable_dtls_srtp == o.enable_dtls_srtp &&
354          ice_candidate_pool_size == o.ice_candidate_pool_size &&
355          prune_turn_ports == o.prune_turn_ports &&
356          turn_port_prune_policy == o.turn_port_prune_policy &&
357          presume_writable_when_fully_relayed ==
358              o.presume_writable_when_fully_relayed &&
359          enable_ice_renomination == o.enable_ice_renomination &&
360          redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
361          surface_ice_candidates_on_ice_transport_type_changed ==
362              o.surface_ice_candidates_on_ice_transport_type_changed &&
363          ice_check_interval_strong_connectivity ==
364              o.ice_check_interval_strong_connectivity &&
365          ice_check_interval_weak_connectivity ==
366              o.ice_check_interval_weak_connectivity &&
367          ice_check_min_interval == o.ice_check_min_interval &&
368          ice_unwritable_timeout == o.ice_unwritable_timeout &&
369          ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
370          ice_inactive_timeout == o.ice_inactive_timeout &&
371          stun_candidate_keepalive_interval ==
372              o.stun_candidate_keepalive_interval &&
373          turn_customizer == o.turn_customizer &&
374          sdp_semantics == o.sdp_semantics &&
375          network_preference == o.network_preference &&
376          active_reset_srtp_params == o.active_reset_srtp_params &&
377          crypto_options == o.crypto_options &&
378          offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
379          turn_logging_id == o.turn_logging_id &&
380          enable_implicit_rollback == o.enable_implicit_rollback &&
381          allow_codec_switching == o.allow_codec_switching &&
382          report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms;
383 }
384 
operator !=(const PeerConnectionInterface::RTCConfiguration & o) const385 bool PeerConnectionInterface::RTCConfiguration::operator!=(
386     const PeerConnectionInterface::RTCConfiguration& o) const {
387   return !(*this == o);
388 }
389 
Create(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)390 rtc::scoped_refptr<PeerConnection> PeerConnection::Create(
391     rtc::scoped_refptr<ConnectionContext> context,
392     const PeerConnectionFactoryInterface::Options& options,
393     std::unique_ptr<RtcEventLog> event_log,
394     std::unique_ptr<Call> call,
395     const PeerConnectionInterface::RTCConfiguration& configuration,
396     PeerConnectionDependencies dependencies) {
397   RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
398       ParseIceConfig(configuration));
399   if (!config_error.ok()) {
400     RTC_LOG(LS_ERROR) << "Invalid configuration: " << config_error.message();
401     return nullptr;
402   }
403 
404   if (!dependencies.allocator) {
405     RTC_LOG(LS_ERROR)
406         << "PeerConnection initialized without a PortAllocator? "
407            "This shouldn't happen if using PeerConnectionFactory.";
408     return nullptr;
409   }
410 
411   if (!dependencies.observer) {
412     // TODO(deadbeef): Why do we do this?
413     RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
414                          "PeerConnectionObserver";
415     return nullptr;
416   }
417 
418   bool is_unified_plan =
419       configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
420   // The PeerConnection constructor consumes some, but not all, dependencies.
421   rtc::scoped_refptr<PeerConnection> pc(
422       new rtc::RefCountedObject<PeerConnection>(
423           context, options, is_unified_plan, std::move(event_log),
424           std::move(call), dependencies));
425   if (!pc->Initialize(configuration, std::move(dependencies))) {
426     return nullptr;
427   }
428   return pc;
429 }
430 
PeerConnection(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)431 PeerConnection::PeerConnection(
432     rtc::scoped_refptr<ConnectionContext> context,
433     const PeerConnectionFactoryInterface::Options& options,
434     bool is_unified_plan,
435     std::unique_ptr<RtcEventLog> event_log,
436     std::unique_ptr<Call> call,
437     PeerConnectionDependencies& dependencies)
438     : context_(context),
439       options_(options),
440       observer_(dependencies.observer),
441       is_unified_plan_(is_unified_plan),
442       event_log_(std::move(event_log)),
443       event_log_ptr_(event_log_.get()),
444       async_resolver_factory_(std::move(dependencies.async_resolver_factory)),
445       port_allocator_(std::move(dependencies.allocator)),
446       ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
447       tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
448       call_(std::move(call)),
449       call_ptr_(call_.get()),
450       data_channel_controller_(this),
451       message_handler_(signaling_thread()) {}
452 
~PeerConnection()453 PeerConnection::~PeerConnection() {
454   TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
455   RTC_DCHECK_RUN_ON(signaling_thread());
456 
457   if (sdp_handler_) {
458     sdp_handler_->PrepareForShutdown();
459   }
460 
461   // Need to stop transceivers before destroying the stats collector because
462   // AudioRtpSender has a reference to the StatsCollector it will update when
463   // stopping.
464   if (rtp_manager()) {
465     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
466       transceiver->StopInternal();
467     }
468   }
469 
470   stats_.reset(nullptr);
471   if (stats_collector_) {
472     stats_collector_->WaitForPendingRequest();
473     stats_collector_ = nullptr;
474   }
475 
476   if (sdp_handler_) {
477     // Don't destroy BaseChannels until after stats has been cleaned up so that
478     // the last stats request can still read from the channels.
479     sdp_handler_->DestroyAllChannels();
480 
481     RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
482 
483     sdp_handler_->ResetSessionDescFactory();
484   }
485   transport_controller_.reset();
486 
487   // port_allocator_ lives on the network thread and should be destroyed there.
488   network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
489     RTC_DCHECK_RUN_ON(network_thread());
490     port_allocator_.reset();
491   });
492   // call_ and event_log_ must be destroyed on the worker thread.
493   worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
494     RTC_DCHECK_RUN_ON(worker_thread());
495     call_safety_.reset();
496     call_.reset();
497     // The event log must outlive call (and any other object that uses it).
498     event_log_.reset();
499   });
500 }
501 
Initialize(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)502 bool PeerConnection::Initialize(
503     const PeerConnectionInterface::RTCConfiguration& configuration,
504     PeerConnectionDependencies dependencies) {
505   RTC_DCHECK_RUN_ON(signaling_thread());
506   TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
507 
508   cricket::ServerAddresses stun_servers;
509   std::vector<cricket::RelayServerConfig> turn_servers;
510 
511   RTCErrorType parse_error =
512       ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
513   if (parse_error != RTCErrorType::NONE) {
514     return false;
515   }
516 
517   // Add the turn logging id to all turn servers
518   for (cricket::RelayServerConfig& turn_server : turn_servers) {
519     turn_server.turn_logging_id = configuration.turn_logging_id;
520   }
521 
522   // The port allocator lives on the network thread and should be initialized
523   // there.
524   const auto pa_result =
525       network_thread()->Invoke<InitializePortAllocatorResult>(
526           RTC_FROM_HERE,
527           rtc::Bind(&PeerConnection::InitializePortAllocator_n, this,
528                     stun_servers, turn_servers, configuration));
529 
530   // Note if STUN or TURN servers were supplied.
531   if (!stun_servers.empty()) {
532     NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
533   }
534   if (!turn_servers.empty()) {
535     NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
536   }
537 
538   // Send information about IPv4/IPv6 status.
539   PeerConnectionAddressFamilyCounter address_family;
540   if (pa_result.enable_ipv6) {
541     address_family = kPeerConnection_IPv6;
542   } else {
543     address_family = kPeerConnection_IPv4;
544   }
545   RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
546                             kPeerConnectionAddressFamilyCounter_Max);
547 
548   // RFC 3264: The numeric value of the session id and version in the
549   // o line MUST be representable with a "64 bit signed integer".
550   // Due to this constraint session id |session_id_| is max limited to
551   // LLONG_MAX.
552   session_id_ = rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX);
553   JsepTransportController::Config config;
554   config.redetermine_role_on_ice_restart =
555       configuration.redetermine_role_on_ice_restart;
556   config.ssl_max_version = options_.ssl_max_version;
557   config.disable_encryption = options_.disable_encryption;
558   config.bundle_policy = configuration.bundle_policy;
559   config.rtcp_mux_policy = configuration.rtcp_mux_policy;
560   // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
561   // this stub.
562   config.crypto_options = configuration.crypto_options.has_value()
563                               ? *configuration.crypto_options
564                               : options_.crypto_options;
565   config.transport_observer = this;
566   config.rtcp_handler = InitializeRtcpCallback();
567   config.event_log = event_log_ptr_;
568 #if defined(ENABLE_EXTERNAL_AUTH)
569   config.enable_external_auth = true;
570 #endif
571   config.active_reset_srtp_params = configuration.active_reset_srtp_params;
572 
573   if (options_.disable_encryption) {
574     dtls_enabled_ = false;
575   } else {
576     // Enable DTLS by default if we have an identity store or a certificate.
577     dtls_enabled_ =
578         (dependencies.cert_generator || !configuration.certificates.empty());
579     // |configuration| can override the default |dtls_enabled_| value.
580     if (configuration.enable_dtls_srtp) {
581       dtls_enabled_ = *(configuration.enable_dtls_srtp);
582     }
583   }
584 
585   if (configuration.enable_rtp_data_channel) {
586     // Enable creation of RTP data channels if the kEnableRtpDataChannels is
587     // set. It takes precendence over the disable_sctp_data_channels
588     // PeerConnectionFactoryInterface::Options.
589     data_channel_controller_.set_data_channel_type(cricket::DCT_RTP);
590   } else {
591     // DTLS has to be enabled to use SCTP.
592     if (!options_.disable_sctp_data_channels && dtls_enabled_) {
593       data_channel_controller_.set_data_channel_type(cricket::DCT_SCTP);
594       config.sctp_factory = context_->sctp_transport_factory();
595     }
596   }
597 
598   config.ice_transport_factory = ice_transport_factory_.get();
599 
600   transport_controller_.reset(new JsepTransportController(
601       signaling_thread(), network_thread(), port_allocator_.get(),
602       async_resolver_factory_.get(), config));
603   transport_controller_->SignalStandardizedIceConnectionState.connect(
604       this, &PeerConnection::SetStandardizedIceConnectionState);
605   transport_controller_->SignalConnectionState.connect(
606       this, &PeerConnection::SetConnectionState);
607   transport_controller_->SignalIceGatheringState.connect(
608       this, &PeerConnection::OnTransportControllerGatheringState);
609   transport_controller_->SignalIceCandidatesGathered.connect(
610       this, &PeerConnection::OnTransportControllerCandidatesGathered);
611   transport_controller_->SignalIceCandidateError.connect(
612       this, &PeerConnection::OnTransportControllerCandidateError);
613   transport_controller_->SignalIceCandidatesRemoved.connect(
614       this, &PeerConnection::OnTransportControllerCandidatesRemoved);
615   transport_controller_->SignalDtlsHandshakeError.connect(
616       this, &PeerConnection::OnTransportControllerDtlsHandshakeError);
617   transport_controller_->SignalIceCandidatePairChanged.connect(
618       this, &PeerConnection::OnTransportControllerCandidateChanged);
619 
620   transport_controller_->SignalIceConnectionState.AddReceiver(
621       [this](cricket::IceConnectionState s) {
622         RTC_DCHECK_RUN_ON(signaling_thread());
623         OnTransportControllerConnectionState(s);
624       });
625 
626   configuration_ = configuration;
627 
628   transport_controller_->SetIceConfig(ParseIceConfig(configuration));
629 
630   stats_ = std::make_unique<StatsCollector>(this);
631   stats_collector_ = RTCStatsCollector::Create(this);
632 
633   sdp_handler_ =
634       SdpOfferAnswerHandler::Create(this, configuration, dependencies);
635 
636   rtp_manager_ = std::make_unique<RtpTransmissionManager>(
637       IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
638       &usage_pattern_, observer_, stats_.get(), [this]() {
639         RTC_DCHECK_RUN_ON(signaling_thread());
640         sdp_handler_->UpdateNegotiationNeeded();
641       });
642 
643   // Add default audio/video transceivers for Plan B SDP.
644   if (!IsUnifiedPlan()) {
645     rtp_manager()->transceivers()->Add(
646         RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
647             signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_AUDIO)));
648     rtp_manager()->transceivers()->Add(
649         RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
650             signaling_thread(), new RtpTransceiver(cricket::MEDIA_TYPE_VIDEO)));
651   }
652 
653   int delay_ms = configuration.report_usage_pattern_delay_ms
654                      ? *configuration.report_usage_pattern_delay_ms
655                      : REPORT_USAGE_PATTERN_DELAY_MS;
656   message_handler_.RequestUsagePatternReport(
657       [this]() {
658         RTC_DCHECK_RUN_ON(signaling_thread());
659         ReportUsagePattern();
660       },
661       delay_ms);
662 
663   return true;
664 }
665 
local_streams()666 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
667   RTC_DCHECK_RUN_ON(signaling_thread());
668   RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
669                                  "Plan SdpSemantics. Please use GetSenders "
670                                  "instead.";
671   return sdp_handler_->local_streams();
672 }
673 
remote_streams()674 rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
675   RTC_DCHECK_RUN_ON(signaling_thread());
676   RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
677                                  "Plan SdpSemantics. Please use GetReceivers "
678                                  "instead.";
679   return sdp_handler_->remote_streams();
680 }
681 
AddStream(MediaStreamInterface * local_stream)682 bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
683   RTC_DCHECK_RUN_ON(signaling_thread());
684   RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
685                                  "SdpSemantics. Please use AddTrack instead.";
686   TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
687   return sdp_handler_->AddStream(local_stream);
688 }
689 
RemoveStream(MediaStreamInterface * local_stream)690 void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
691   RTC_DCHECK_RUN_ON(signaling_thread());
692   RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
693                                  "Plan SdpSemantics. Please use RemoveTrack "
694                                  "instead.";
695   TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
696   sdp_handler_->RemoveStream(local_stream);
697 }
698 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids)699 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
700     rtc::scoped_refptr<MediaStreamTrackInterface> track,
701     const std::vector<std::string>& stream_ids) {
702   RTC_DCHECK_RUN_ON(signaling_thread());
703   TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
704   if (!track) {
705     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
706   }
707   if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
708         track->kind() == MediaStreamTrackInterface::kVideoKind)) {
709     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
710                          "Track has invalid kind: " + track->kind());
711   }
712   if (IsClosed()) {
713     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
714                          "PeerConnection is closed.");
715   }
716   if (rtp_manager()->FindSenderForTrack(track)) {
717     LOG_AND_RETURN_ERROR(
718         RTCErrorType::INVALID_PARAMETER,
719         "Sender already exists for track " + track->id() + ".");
720   }
721   auto sender_or_error = rtp_manager()->AddTrack(track, stream_ids);
722   if (sender_or_error.ok()) {
723     sdp_handler_->UpdateNegotiationNeeded();
724     stats_->AddTrack(track);
725   }
726   return sender_or_error;
727 }
728 
RemoveTrack(RtpSenderInterface * sender)729 bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) {
730   TRACE_EVENT0("webrtc", "PeerConnection::RemoveTrack");
731   return RemoveTrackNew(sender).ok();
732 }
733 
RemoveTrackNew(rtc::scoped_refptr<RtpSenderInterface> sender)734 RTCError PeerConnection::RemoveTrackNew(
735     rtc::scoped_refptr<RtpSenderInterface> sender) {
736   RTC_DCHECK_RUN_ON(signaling_thread());
737   if (!sender) {
738     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
739   }
740   if (IsClosed()) {
741     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
742                          "PeerConnection is closed.");
743   }
744   if (IsUnifiedPlan()) {
745     auto transceiver = FindTransceiverBySender(sender);
746     if (!transceiver || !sender->track()) {
747       return RTCError::OK();
748     }
749     sender->SetTrack(nullptr);
750     if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
751       transceiver->internal()->set_direction(
752           RtpTransceiverDirection::kRecvOnly);
753     } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
754       transceiver->internal()->set_direction(
755           RtpTransceiverDirection::kInactive);
756     }
757   } else {
758     bool removed;
759     if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
760       removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
761           sender);
762     } else {
763       RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
764       removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
765           sender);
766     }
767     if (!removed) {
768       LOG_AND_RETURN_ERROR(
769           RTCErrorType::INVALID_PARAMETER,
770           "Couldn't find sender " + sender->id() + " to remove.");
771     }
772   }
773   sdp_handler_->UpdateNegotiationNeeded();
774   return RTCError::OK();
775 }
776 
777 rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
FindTransceiverBySender(rtc::scoped_refptr<RtpSenderInterface> sender)778 PeerConnection::FindTransceiverBySender(
779     rtc::scoped_refptr<RtpSenderInterface> sender) {
780   return rtp_manager()->transceivers()->FindBySender(sender);
781 }
782 
783 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track)784 PeerConnection::AddTransceiver(
785     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
786   return AddTransceiver(track, RtpTransceiverInit());
787 }
788 
789 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init)790 PeerConnection::AddTransceiver(
791     rtc::scoped_refptr<MediaStreamTrackInterface> track,
792     const RtpTransceiverInit& init) {
793   RTC_DCHECK_RUN_ON(signaling_thread());
794   RTC_CHECK(IsUnifiedPlan())
795       << "AddTransceiver is only available with Unified Plan SdpSemantics";
796   if (!track) {
797     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
798   }
799   cricket::MediaType media_type;
800   if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
801     media_type = cricket::MEDIA_TYPE_AUDIO;
802   } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
803     media_type = cricket::MEDIA_TYPE_VIDEO;
804   } else {
805     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
806                          "Track kind is not audio or video");
807   }
808   return AddTransceiver(media_type, track, init);
809 }
810 
811 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type)812 PeerConnection::AddTransceiver(cricket::MediaType media_type) {
813   return AddTransceiver(media_type, RtpTransceiverInit());
814 }
815 
816 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,const RtpTransceiverInit & init)817 PeerConnection::AddTransceiver(cricket::MediaType media_type,
818                                const RtpTransceiverInit& init) {
819   RTC_DCHECK_RUN_ON(signaling_thread());
820   RTC_CHECK(IsUnifiedPlan())
821       << "AddTransceiver is only available with Unified Plan SdpSemantics";
822   if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
823         media_type == cricket::MEDIA_TYPE_VIDEO)) {
824     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
825                          "media type is not audio or video");
826   }
827   return AddTransceiver(media_type, nullptr, init);
828 }
829 
830 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(cricket::MediaType media_type,rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init,bool update_negotiation_needed)831 PeerConnection::AddTransceiver(
832     cricket::MediaType media_type,
833     rtc::scoped_refptr<MediaStreamTrackInterface> track,
834     const RtpTransceiverInit& init,
835     bool update_negotiation_needed) {
836   RTC_DCHECK_RUN_ON(signaling_thread());
837   RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
838               media_type == cricket::MEDIA_TYPE_VIDEO));
839   if (track) {
840     RTC_DCHECK_EQ(media_type,
841                   (track->kind() == MediaStreamTrackInterface::kAudioKind
842                        ? cricket::MEDIA_TYPE_AUDIO
843                        : cricket::MEDIA_TYPE_VIDEO));
844   }
845 
846   RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
847                               init.send_encodings.size(), 0, 7, 8);
848 
849   size_t num_rids = absl::c_count_if(init.send_encodings,
850                                      [](const RtpEncodingParameters& encoding) {
851                                        return !encoding.rid.empty();
852                                      });
853   if (num_rids > 0 && num_rids != init.send_encodings.size()) {
854     LOG_AND_RETURN_ERROR(
855         RTCErrorType::INVALID_PARAMETER,
856         "RIDs must be provided for either all or none of the send encodings.");
857   }
858 
859   if (num_rids > 0 && absl::c_any_of(init.send_encodings,
860                                      [](const RtpEncodingParameters& encoding) {
861                                        return !IsLegalRsidName(encoding.rid);
862                                      })) {
863     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
864                          "Invalid RID value provided.");
865   }
866 
867   if (absl::c_any_of(init.send_encodings,
868                      [](const RtpEncodingParameters& encoding) {
869                        return encoding.ssrc.has_value();
870                      })) {
871     LOG_AND_RETURN_ERROR(
872         RTCErrorType::UNSUPPORTED_PARAMETER,
873         "Attempted to set an unimplemented parameter of RtpParameters.");
874   }
875 
876   RtpParameters parameters;
877   parameters.encodings = init.send_encodings;
878 
879   // Encodings are dropped from the tail if too many are provided.
880   if (parameters.encodings.size() > kMaxSimulcastStreams) {
881     parameters.encodings.erase(
882         parameters.encodings.begin() + kMaxSimulcastStreams,
883         parameters.encodings.end());
884   }
885 
886   // Single RID should be removed.
887   if (parameters.encodings.size() == 1 &&
888       !parameters.encodings[0].rid.empty()) {
889     RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
890     parameters.encodings[0].rid.clear();
891   }
892 
893   // If RIDs were not provided, they are generated for simulcast scenario.
894   if (parameters.encodings.size() > 1 && num_rids == 0) {
895     rtc::UniqueStringGenerator rid_generator;
896     for (RtpEncodingParameters& encoding : parameters.encodings) {
897       encoding.rid = rid_generator();
898     }
899   }
900 
901   if (UnimplementedRtpParameterHasValue(parameters)) {
902     LOG_AND_RETURN_ERROR(
903         RTCErrorType::UNSUPPORTED_PARAMETER,
904         "Attempted to set an unimplemented parameter of RtpParameters.");
905   }
906 
907   auto result = cricket::CheckRtpParametersValues(parameters);
908   if (!result.ok()) {
909     LOG_AND_RETURN_ERROR(result.type(), result.message());
910   }
911 
912   RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
913                    << " transceiver in response to a call to AddTransceiver.";
914   // Set the sender ID equal to the track ID if the track is specified unless
915   // that sender ID is already in use.
916   std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
917                                ? track->id()
918                                : rtc::CreateRandomUuid());
919   auto sender = rtp_manager()->CreateSender(
920       media_type, sender_id, track, init.stream_ids, parameters.encodings);
921   auto receiver =
922       rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
923   auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
924   transceiver->internal()->set_direction(init.direction);
925 
926   if (update_negotiation_needed) {
927     sdp_handler_->UpdateNegotiationNeeded();
928   }
929 
930   return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
931 }
932 
OnNegotiationNeeded()933 void PeerConnection::OnNegotiationNeeded() {
934   RTC_DCHECK_RUN_ON(signaling_thread());
935   RTC_DCHECK(!IsClosed());
936   sdp_handler_->UpdateNegotiationNeeded();
937 }
938 
CreateSender(const std::string & kind,const std::string & stream_id)939 rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
940     const std::string& kind,
941     const std::string& stream_id) {
942   RTC_DCHECK_RUN_ON(signaling_thread());
943   RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
944                                  "Plan SdpSemantics. Please use AddTransceiver "
945                                  "instead.";
946   TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
947   if (IsClosed()) {
948     return nullptr;
949   }
950 
951   // Internally we need to have one stream with Plan B semantics, so we
952   // generate a random stream ID if not specified.
953   std::vector<std::string> stream_ids;
954   if (stream_id.empty()) {
955     stream_ids.push_back(rtc::CreateRandomUuid());
956     RTC_LOG(LS_INFO)
957         << "No stream_id specified for sender. Generated stream ID: "
958         << stream_ids[0];
959   } else {
960     stream_ids.push_back(stream_id);
961   }
962 
963   // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
964   rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
965   if (kind == MediaStreamTrackInterface::kAudioKind) {
966     auto audio_sender = AudioRtpSender::Create(
967         worker_thread(), rtc::CreateRandomUuid(), stats_.get(), rtp_manager());
968     audio_sender->SetMediaChannel(rtp_manager()->voice_media_channel());
969     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
970         signaling_thread(), audio_sender);
971     rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
972   } else if (kind == MediaStreamTrackInterface::kVideoKind) {
973     auto video_sender = VideoRtpSender::Create(
974         worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
975     video_sender->SetMediaChannel(rtp_manager()->video_media_channel());
976     new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
977         signaling_thread(), video_sender);
978     rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
979   } else {
980     RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
981     return nullptr;
982   }
983   new_sender->internal()->set_stream_ids(stream_ids);
984 
985   return new_sender;
986 }
987 
GetSenders() const988 std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
989     const {
990   RTC_DCHECK_RUN_ON(signaling_thread());
991   std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
992   for (const auto& sender : rtp_manager()->GetSendersInternal()) {
993     ret.push_back(sender);
994   }
995   return ret;
996 }
997 
998 std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
GetReceivers() const999 PeerConnection::GetReceivers() const {
1000   RTC_DCHECK_RUN_ON(signaling_thread());
1001   std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
1002   for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1003     ret.push_back(receiver);
1004   }
1005   return ret;
1006 }
1007 
1008 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
GetTransceivers() const1009 PeerConnection::GetTransceivers() const {
1010   RTC_DCHECK_RUN_ON(signaling_thread());
1011   RTC_CHECK(IsUnifiedPlan())
1012       << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
1013   std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
1014   for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1015     all_transceivers.push_back(transceiver);
1016   }
1017   return all_transceivers;
1018 }
1019 
GetStats(StatsObserver * observer,MediaStreamTrackInterface * track,StatsOutputLevel level)1020 bool PeerConnection::GetStats(StatsObserver* observer,
1021                               MediaStreamTrackInterface* track,
1022                               StatsOutputLevel level) {
1023   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1024   RTC_DCHECK_RUN_ON(signaling_thread());
1025   if (!observer) {
1026     RTC_LOG(LS_ERROR) << "GetStats - observer is NULL.";
1027     return false;
1028   }
1029 
1030   stats_->UpdateStats(level);
1031   // The StatsCollector is used to tell if a track is valid because it may
1032   // remember tracks that the PeerConnection previously removed.
1033   if (track && !stats_->IsValidTrack(track->id())) {
1034     RTC_LOG(LS_WARNING) << "GetStats is called with an invalid track: "
1035                         << track->id();
1036     return false;
1037   }
1038   message_handler_.PostGetStats(observer, stats_.get(), track);
1039   return true;
1040 }
1041 
GetStats(RTCStatsCollectorCallback * callback)1042 void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
1043   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1044   RTC_DCHECK_RUN_ON(signaling_thread());
1045   RTC_DCHECK(stats_collector_);
1046   RTC_DCHECK(callback);
1047   stats_collector_->GetStatsReport(callback);
1048 }
1049 
GetStats(rtc::scoped_refptr<RtpSenderInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1050 void PeerConnection::GetStats(
1051     rtc::scoped_refptr<RtpSenderInterface> selector,
1052     rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1053   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1054   RTC_DCHECK_RUN_ON(signaling_thread());
1055   RTC_DCHECK(callback);
1056   RTC_DCHECK(stats_collector_);
1057   rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1058   if (selector) {
1059     for (const auto& proxy_transceiver :
1060          rtp_manager()->transceivers()->List()) {
1061       for (const auto& proxy_sender :
1062            proxy_transceiver->internal()->senders()) {
1063         if (proxy_sender == selector) {
1064           internal_sender = proxy_sender->internal();
1065           break;
1066         }
1067       }
1068       if (internal_sender)
1069         break;
1070     }
1071   }
1072   // If there is no |internal_sender| then |selector| is either null or does not
1073   // belong to the PeerConnection (in Plan B, senders can be removed from the
1074   // PeerConnection). This means that "all the stats objects representing the
1075   // selector" is an empty set. Invoking GetStatsReport() with a null selector
1076   // produces an empty stats report.
1077   stats_collector_->GetStatsReport(internal_sender, callback);
1078 }
1079 
GetStats(rtc::scoped_refptr<RtpReceiverInterface> selector,rtc::scoped_refptr<RTCStatsCollectorCallback> callback)1080 void PeerConnection::GetStats(
1081     rtc::scoped_refptr<RtpReceiverInterface> selector,
1082     rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1083   TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
1084   RTC_DCHECK_RUN_ON(signaling_thread());
1085   RTC_DCHECK(callback);
1086   RTC_DCHECK(stats_collector_);
1087   rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1088   if (selector) {
1089     for (const auto& proxy_transceiver :
1090          rtp_manager()->transceivers()->List()) {
1091       for (const auto& proxy_receiver :
1092            proxy_transceiver->internal()->receivers()) {
1093         if (proxy_receiver == selector) {
1094           internal_receiver = proxy_receiver->internal();
1095           break;
1096         }
1097       }
1098       if (internal_receiver)
1099         break;
1100     }
1101   }
1102   // If there is no |internal_receiver| then |selector| is either null or does
1103   // not belong to the PeerConnection (in Plan B, receivers can be removed from
1104   // the PeerConnection). This means that "all the stats objects representing
1105   // the selector" is an empty set. Invoking GetStatsReport() with a null
1106   // selector produces an empty stats report.
1107   stats_collector_->GetStatsReport(internal_receiver, callback);
1108 }
1109 
signaling_state()1110 PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
1111   RTC_DCHECK_RUN_ON(signaling_thread());
1112   return sdp_handler_->signaling_state();
1113 }
1114 
1115 PeerConnectionInterface::IceConnectionState
ice_connection_state()1116 PeerConnection::ice_connection_state() {
1117   RTC_DCHECK_RUN_ON(signaling_thread());
1118   return ice_connection_state_;
1119 }
1120 
1121 PeerConnectionInterface::IceConnectionState
standardized_ice_connection_state()1122 PeerConnection::standardized_ice_connection_state() {
1123   RTC_DCHECK_RUN_ON(signaling_thread());
1124   return standardized_ice_connection_state_;
1125 }
1126 
1127 PeerConnectionInterface::PeerConnectionState
peer_connection_state()1128 PeerConnection::peer_connection_state() {
1129   RTC_DCHECK_RUN_ON(signaling_thread());
1130   return connection_state_;
1131 }
1132 
1133 PeerConnectionInterface::IceGatheringState
ice_gathering_state()1134 PeerConnection::ice_gathering_state() {
1135   RTC_DCHECK_RUN_ON(signaling_thread());
1136   return ice_gathering_state_;
1137 }
1138 
can_trickle_ice_candidates()1139 absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1140   RTC_DCHECK_RUN_ON(signaling_thread());
1141   const SessionDescriptionInterface* description = current_remote_description();
1142   if (!description) {
1143     description = pending_remote_description();
1144   }
1145   if (!description) {
1146     return absl::nullopt;
1147   }
1148   // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1149   if (description->description()->transport_infos().size() < 1) {
1150     return absl::nullopt;
1151   }
1152   return description->description()->transport_infos()[0].description.HasOption(
1153       "trickle");
1154 }
1155 
CreateDataChannel(const std::string & label,const DataChannelInit * config)1156 rtc::scoped_refptr<DataChannelInterface> PeerConnection::CreateDataChannel(
1157     const std::string& label,
1158     const DataChannelInit* config) {
1159   RTC_DCHECK_RUN_ON(signaling_thread());
1160   TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
1161 
1162   bool first_datachannel = !data_channel_controller_.HasDataChannels();
1163 
1164   std::unique_ptr<InternalDataChannelInit> internal_config;
1165   if (config) {
1166     internal_config.reset(new InternalDataChannelInit(*config));
1167   }
1168   rtc::scoped_refptr<DataChannelInterface> channel(
1169       data_channel_controller_.InternalCreateDataChannelWithProxy(
1170           label, internal_config.get()));
1171   if (!channel.get()) {
1172     return nullptr;
1173   }
1174 
1175   // Trigger the onRenegotiationNeeded event for every new RTP DataChannel, or
1176   // the first SCTP DataChannel.
1177   if (data_channel_type() == cricket::DCT_RTP || first_datachannel) {
1178     sdp_handler_->UpdateNegotiationNeeded();
1179   }
1180   NoteUsageEvent(UsageEvent::DATA_ADDED);
1181   return channel;
1182 }
1183 
RestartIce()1184 void PeerConnection::RestartIce() {
1185   RTC_DCHECK_RUN_ON(signaling_thread());
1186   sdp_handler_->RestartIce();
1187 }
1188 
CreateOffer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1189 void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
1190                                  const RTCOfferAnswerOptions& options) {
1191   RTC_DCHECK_RUN_ON(signaling_thread());
1192   sdp_handler_->CreateOffer(observer, options);
1193 }
1194 
CreateAnswer(CreateSessionDescriptionObserver * observer,const RTCOfferAnswerOptions & options)1195 void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1196                                   const RTCOfferAnswerOptions& options) {
1197   RTC_DCHECK_RUN_ON(signaling_thread());
1198   sdp_handler_->CreateAnswer(observer, options);
1199 }
1200 
SetLocalDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1201 void PeerConnection::SetLocalDescription(
1202     SetSessionDescriptionObserver* observer,
1203     SessionDescriptionInterface* desc_ptr) {
1204   RTC_DCHECK_RUN_ON(signaling_thread());
1205   sdp_handler_->SetLocalDescription(observer, desc_ptr);
1206 }
1207 
SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1208 void PeerConnection::SetLocalDescription(
1209     std::unique_ptr<SessionDescriptionInterface> desc,
1210     rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1211   RTC_DCHECK_RUN_ON(signaling_thread());
1212   sdp_handler_->SetLocalDescription(std::move(desc), observer);
1213 }
1214 
SetLocalDescription(SetSessionDescriptionObserver * observer)1215 void PeerConnection::SetLocalDescription(
1216     SetSessionDescriptionObserver* observer) {
1217   RTC_DCHECK_RUN_ON(signaling_thread());
1218   sdp_handler_->SetLocalDescription(observer);
1219 }
1220 
SetLocalDescription(rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer)1221 void PeerConnection::SetLocalDescription(
1222     rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1223   RTC_DCHECK_RUN_ON(signaling_thread());
1224   sdp_handler_->SetLocalDescription(observer);
1225 }
1226 
SetRemoteDescription(SetSessionDescriptionObserver * observer,SessionDescriptionInterface * desc_ptr)1227 void PeerConnection::SetRemoteDescription(
1228     SetSessionDescriptionObserver* observer,
1229     SessionDescriptionInterface* desc_ptr) {
1230   RTC_DCHECK_RUN_ON(signaling_thread());
1231   sdp_handler_->SetRemoteDescription(observer, desc_ptr);
1232 }
1233 
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer)1234 void PeerConnection::SetRemoteDescription(
1235     std::unique_ptr<SessionDescriptionInterface> desc,
1236     rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
1237   RTC_DCHECK_RUN_ON(signaling_thread());
1238   sdp_handler_->SetRemoteDescription(std::move(desc), observer);
1239 }
1240 
GetConfiguration()1241 PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
1242   RTC_DCHECK_RUN_ON(signaling_thread());
1243   return configuration_;
1244 }
1245 
SetConfiguration(const RTCConfiguration & configuration)1246 RTCError PeerConnection::SetConfiguration(
1247     const RTCConfiguration& configuration) {
1248   RTC_DCHECK_RUN_ON(signaling_thread());
1249   TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
1250   if (IsClosed()) {
1251     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1252                          "SetConfiguration: PeerConnection is closed.");
1253   }
1254 
1255   // According to JSEP, after setLocalDescription, changing the candidate pool
1256   // size is not allowed, and changing the set of ICE servers will not result
1257   // in new candidates being gathered.
1258   if (local_description() && configuration.ice_candidate_pool_size !=
1259                                  configuration_.ice_candidate_pool_size) {
1260     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1261                          "Can't change candidate pool size after calling "
1262                          "SetLocalDescription.");
1263   }
1264 
1265   if (local_description() &&
1266       configuration.crypto_options != configuration_.crypto_options) {
1267     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1268                          "Can't change crypto_options after calling "
1269                          "SetLocalDescription.");
1270   }
1271 
1272   // The simplest (and most future-compatible) way to tell if the config was
1273   // modified in an invalid way is to copy each property we do support
1274   // modifying, then use operator==. There are far more properties we don't
1275   // support modifying than those we do, and more could be added.
1276   RTCConfiguration modified_config = configuration_;
1277   modified_config.servers = configuration.servers;
1278   modified_config.type = configuration.type;
1279   modified_config.ice_candidate_pool_size =
1280       configuration.ice_candidate_pool_size;
1281   modified_config.prune_turn_ports = configuration.prune_turn_ports;
1282   modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
1283   modified_config.surface_ice_candidates_on_ice_transport_type_changed =
1284       configuration.surface_ice_candidates_on_ice_transport_type_changed;
1285   modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
1286   modified_config.ice_check_interval_strong_connectivity =
1287       configuration.ice_check_interval_strong_connectivity;
1288   modified_config.ice_check_interval_weak_connectivity =
1289       configuration.ice_check_interval_weak_connectivity;
1290   modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
1291   modified_config.ice_unwritable_min_checks =
1292       configuration.ice_unwritable_min_checks;
1293   modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
1294   modified_config.stun_candidate_keepalive_interval =
1295       configuration.stun_candidate_keepalive_interval;
1296   modified_config.turn_customizer = configuration.turn_customizer;
1297   modified_config.network_preference = configuration.network_preference;
1298   modified_config.active_reset_srtp_params =
1299       configuration.active_reset_srtp_params;
1300   modified_config.turn_logging_id = configuration.turn_logging_id;
1301   modified_config.allow_codec_switching = configuration.allow_codec_switching;
1302   if (configuration != modified_config) {
1303     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1304                          "Modifying the configuration in an unsupported way.");
1305   }
1306 
1307   // Validate the modified configuration.
1308   RTCError validate_error = ValidateConfiguration(modified_config);
1309   if (!validate_error.ok()) {
1310     return validate_error;
1311   }
1312 
1313   // Note that this isn't possible through chromium, since it's an unsigned
1314   // short in WebIDL.
1315   if (configuration.ice_candidate_pool_size < 0 ||
1316       configuration.ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
1317     return RTCError(RTCErrorType::INVALID_RANGE);
1318   }
1319 
1320   // Parse ICE servers before hopping to network thread.
1321   cricket::ServerAddresses stun_servers;
1322   std::vector<cricket::RelayServerConfig> turn_servers;
1323   RTCErrorType parse_error =
1324       ParseIceServers(configuration.servers, &stun_servers, &turn_servers);
1325   if (parse_error != RTCErrorType::NONE) {
1326     return RTCError(parse_error);
1327   }
1328   // Add the turn logging id to all turn servers
1329   for (cricket::RelayServerConfig& turn_server : turn_servers) {
1330     turn_server.turn_logging_id = configuration.turn_logging_id;
1331   }
1332 
1333   // Note if STUN or TURN servers were supplied.
1334   if (!stun_servers.empty()) {
1335     NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
1336   }
1337   if (!turn_servers.empty()) {
1338     NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
1339   }
1340 
1341   // In theory this shouldn't fail.
1342   if (!network_thread()->Invoke<bool>(
1343           RTC_FROM_HERE,
1344           rtc::Bind(&PeerConnection::ReconfigurePortAllocator_n, this,
1345                     stun_servers, turn_servers, modified_config.type,
1346                     modified_config.ice_candidate_pool_size,
1347                     modified_config.GetTurnPortPrunePolicy(),
1348                     modified_config.turn_customizer,
1349                     modified_config.stun_candidate_keepalive_interval,
1350                     static_cast<bool>(local_description())))) {
1351     LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1352                          "Failed to apply configuration to PortAllocator.");
1353   }
1354 
1355   // As described in JSEP, calling setConfiguration with new ICE servers or
1356   // candidate policy must set a "needs-ice-restart" bit so that the next offer
1357   // triggers an ICE restart which will pick up the changes.
1358   if (modified_config.servers != configuration_.servers ||
1359       NeedIceRestart(
1360           configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1361           configuration_.type, modified_config.type) ||
1362       modified_config.GetTurnPortPrunePolicy() !=
1363           configuration_.GetTurnPortPrunePolicy()) {
1364     transport_controller_->SetNeedsIceRestartFlag();
1365   }
1366 
1367   transport_controller_->SetIceConfig(ParseIceConfig(modified_config));
1368 
1369   if (configuration_.active_reset_srtp_params !=
1370       modified_config.active_reset_srtp_params) {
1371     transport_controller_->SetActiveResetSrtpParams(
1372         modified_config.active_reset_srtp_params);
1373   }
1374 
1375   if (modified_config.allow_codec_switching.has_value()) {
1376     std::vector<cricket::VideoMediaChannel*> channels;
1377     for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1378       if (transceiver->media_type() != cricket::MEDIA_TYPE_VIDEO)
1379         continue;
1380 
1381       auto* video_channel = static_cast<cricket::VideoChannel*>(
1382           transceiver->internal()->channel());
1383       if (video_channel)
1384         channels.push_back(video_channel->media_channel());
1385     }
1386 
1387     worker_thread()->Invoke<void>(
1388         RTC_FROM_HERE,
1389         [channels = std::move(channels),
1390          allow_codec_switching = *modified_config.allow_codec_switching]() {
1391           for (auto* ch : channels)
1392             ch->SetVideoCodecSwitchingEnabled(allow_codec_switching);
1393         });
1394   }
1395 
1396   configuration_ = modified_config;
1397   return RTCError::OK();
1398 }
1399 
AddIceCandidate(const IceCandidateInterface * ice_candidate)1400 bool PeerConnection::AddIceCandidate(
1401     const IceCandidateInterface* ice_candidate) {
1402   RTC_DCHECK_RUN_ON(signaling_thread());
1403   return sdp_handler_->AddIceCandidate(ice_candidate);
1404 }
1405 
AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate,std::function<void (RTCError)> callback)1406 void PeerConnection::AddIceCandidate(
1407     std::unique_ptr<IceCandidateInterface> candidate,
1408     std::function<void(RTCError)> callback) {
1409   RTC_DCHECK_RUN_ON(signaling_thread());
1410   sdp_handler_->AddIceCandidate(std::move(candidate), callback);
1411 }
1412 
RemoveIceCandidates(const std::vector<cricket::Candidate> & candidates)1413 bool PeerConnection::RemoveIceCandidates(
1414     const std::vector<cricket::Candidate>& candidates) {
1415   TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
1416   RTC_DCHECK_RUN_ON(signaling_thread());
1417   return sdp_handler_->RemoveIceCandidates(candidates);
1418 }
1419 
SetBitrate(const BitrateSettings & bitrate)1420 RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
1421   if (!worker_thread()->IsCurrent()) {
1422     return worker_thread()->Invoke<RTCError>(
1423         RTC_FROM_HERE, [&]() { return SetBitrate(bitrate); });
1424   }
1425   RTC_DCHECK_RUN_ON(worker_thread());
1426 
1427   const bool has_min = bitrate.min_bitrate_bps.has_value();
1428   const bool has_start = bitrate.start_bitrate_bps.has_value();
1429   const bool has_max = bitrate.max_bitrate_bps.has_value();
1430   if (has_min && *bitrate.min_bitrate_bps < 0) {
1431     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1432                          "min_bitrate_bps <= 0");
1433   }
1434   if (has_start) {
1435     if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
1436       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1437                            "start_bitrate_bps < min_bitrate_bps");
1438     } else if (*bitrate.start_bitrate_bps < 0) {
1439       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1440                            "curent_bitrate_bps < 0");
1441     }
1442   }
1443   if (has_max) {
1444     if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
1445       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1446                            "max_bitrate_bps < start_bitrate_bps");
1447     } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1448       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1449                            "max_bitrate_bps < min_bitrate_bps");
1450     } else if (*bitrate.max_bitrate_bps < 0) {
1451       LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1452                            "max_bitrate_bps < 0");
1453     }
1454   }
1455 
1456   RTC_DCHECK(call_.get());
1457   call_->SetClientBitratePreferences(bitrate);
1458 
1459   return RTCError::OK();
1460 }
1461 
SetAudioPlayout(bool playout)1462 void PeerConnection::SetAudioPlayout(bool playout) {
1463   if (!worker_thread()->IsCurrent()) {
1464     worker_thread()->Invoke<void>(
1465         RTC_FROM_HERE,
1466         rtc::Bind(&PeerConnection::SetAudioPlayout, this, playout));
1467     return;
1468   }
1469   auto audio_state =
1470       context_->channel_manager()->media_engine()->voice().GetAudioState();
1471   audio_state->SetPlayout(playout);
1472 }
1473 
SetAudioRecording(bool recording)1474 void PeerConnection::SetAudioRecording(bool recording) {
1475   if (!worker_thread()->IsCurrent()) {
1476     worker_thread()->Invoke<void>(
1477         RTC_FROM_HERE,
1478         rtc::Bind(&PeerConnection::SetAudioRecording, this, recording));
1479     return;
1480   }
1481   auto audio_state =
1482       context_->channel_manager()->media_engine()->voice().GetAudioState();
1483   audio_state->SetRecording(recording);
1484 }
1485 
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)1486 void PeerConnection::AddAdaptationResource(
1487     rtc::scoped_refptr<Resource> resource) {
1488   if (!worker_thread()->IsCurrent()) {
1489     return worker_thread()->Invoke<void>(RTC_FROM_HERE, [this, resource]() {
1490       return AddAdaptationResource(resource);
1491     });
1492   }
1493   RTC_DCHECK_RUN_ON(worker_thread());
1494   if (!call_) {
1495     // The PeerConnection has been closed.
1496     return;
1497   }
1498   call_->AddAdaptationResource(resource);
1499 }
1500 
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)1501 bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1502                                       int64_t output_period_ms) {
1503   return worker_thread()->Invoke<bool>(
1504       RTC_FROM_HERE,
1505       [this, output = std::move(output), output_period_ms]() mutable {
1506         return StartRtcEventLog_w(std::move(output), output_period_ms);
1507       });
1508 }
1509 
StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output)1510 bool PeerConnection::StartRtcEventLog(
1511     std::unique_ptr<RtcEventLogOutput> output) {
1512   int64_t output_period_ms = webrtc::RtcEventLog::kImmediateOutput;
1513   if (absl::StartsWith(context_->trials().Lookup("WebRTC-RtcEventLogNewFormat"),
1514                        "Enabled")) {
1515     output_period_ms = 5000;
1516   }
1517   return StartRtcEventLog(std::move(output), output_period_ms);
1518 }
1519 
StopRtcEventLog()1520 void PeerConnection::StopRtcEventLog() {
1521   worker_thread()->Invoke<void>(
1522       RTC_FROM_HERE, rtc::Bind(&PeerConnection::StopRtcEventLog_w, this));
1523 }
1524 
1525 rtc::scoped_refptr<DtlsTransportInterface>
LookupDtlsTransportByMid(const std::string & mid)1526 PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
1527   RTC_DCHECK_RUN_ON(signaling_thread());
1528   return transport_controller_->LookupDtlsTransportByMid(mid);
1529 }
1530 
1531 rtc::scoped_refptr<DtlsTransport>
LookupDtlsTransportByMidInternal(const std::string & mid)1532 PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
1533   RTC_DCHECK_RUN_ON(signaling_thread());
1534   return transport_controller_->LookupDtlsTransportByMid(mid);
1535 }
1536 
GetSctpTransport() const1537 rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1538     const {
1539   RTC_DCHECK_RUN_ON(signaling_thread());
1540   if (!sctp_mid_s_) {
1541     return nullptr;
1542   }
1543   return transport_controller_->GetSctpTransport(*sctp_mid_s_);
1544 }
1545 
local_description() const1546 const SessionDescriptionInterface* PeerConnection::local_description() const {
1547   RTC_DCHECK_RUN_ON(signaling_thread());
1548   return sdp_handler_->local_description();
1549 }
1550 
remote_description() const1551 const SessionDescriptionInterface* PeerConnection::remote_description() const {
1552   RTC_DCHECK_RUN_ON(signaling_thread());
1553   return sdp_handler_->remote_description();
1554 }
1555 
current_local_description() const1556 const SessionDescriptionInterface* PeerConnection::current_local_description()
1557     const {
1558   RTC_DCHECK_RUN_ON(signaling_thread());
1559   return sdp_handler_->current_local_description();
1560 }
1561 
current_remote_description() const1562 const SessionDescriptionInterface* PeerConnection::current_remote_description()
1563     const {
1564   RTC_DCHECK_RUN_ON(signaling_thread());
1565   return sdp_handler_->current_remote_description();
1566 }
1567 
pending_local_description() const1568 const SessionDescriptionInterface* PeerConnection::pending_local_description()
1569     const {
1570   RTC_DCHECK_RUN_ON(signaling_thread());
1571   return sdp_handler_->pending_local_description();
1572 }
1573 
pending_remote_description() const1574 const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1575     const {
1576   RTC_DCHECK_RUN_ON(signaling_thread());
1577   return sdp_handler_->pending_remote_description();
1578 }
1579 
Close()1580 void PeerConnection::Close() {
1581   RTC_DCHECK_RUN_ON(signaling_thread());
1582   TRACE_EVENT0("webrtc", "PeerConnection::Close");
1583 
1584   if (IsClosed()) {
1585     return;
1586   }
1587   // Update stats here so that we have the most recent stats for tracks and
1588   // streams before the channels are closed.
1589   stats_->UpdateStats(kStatsOutputLevelStandard);
1590 
1591   ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1592   Observer()->OnIceConnectionChange(ice_connection_state_);
1593   standardized_ice_connection_state_ =
1594       PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1595   connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1596   Observer()->OnConnectionChange(connection_state_);
1597 
1598   sdp_handler_->Close();
1599 
1600   NoteUsageEvent(UsageEvent::CLOSE_CALLED);
1601 
1602   for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1603     transceiver->internal()->SetPeerConnectionClosed();
1604     if (!transceiver->stopped())
1605       transceiver->StopInternal();
1606   }
1607 
1608   // Ensure that all asynchronous stats requests are completed before destroying
1609   // the transport controller below.
1610   if (stats_collector_) {
1611     stats_collector_->WaitForPendingRequest();
1612   }
1613 
1614   // Don't destroy BaseChannels until after stats has been cleaned up so that
1615   // the last stats request can still read from the channels.
1616   sdp_handler_->DestroyAllChannels();
1617 
1618   // The event log is used in the transport controller, which must be outlived
1619   // by the former. CreateOffer by the peer connection is implemented
1620   // asynchronously and if the peer connection is closed without resetting the
1621   // WebRTC session description factory, the session description factory would
1622   // call the transport controller.
1623   sdp_handler_->ResetSessionDescFactory();
1624   transport_controller_.reset();
1625   rtp_manager_->Close();
1626 
1627   network_thread()->Invoke<void>(
1628       RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::DiscardCandidatePool,
1629                                port_allocator_.get()));
1630 
1631   worker_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
1632     RTC_DCHECK_RUN_ON(worker_thread());
1633     call_safety_.reset();
1634     call_.reset();
1635     // The event log must outlive call (and any other object that uses it).
1636     event_log_.reset();
1637   });
1638   ReportUsagePattern();
1639   // The .h file says that observer can be discarded after close() returns.
1640   // Make sure this is true.
1641   observer_ = nullptr;
1642 }
1643 
SetIceConnectionState(IceConnectionState new_state)1644 void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
1645   RTC_DCHECK_RUN_ON(signaling_thread());
1646   if (ice_connection_state_ == new_state) {
1647     return;
1648   }
1649 
1650   // After transitioning to "closed", ignore any additional states from
1651   // TransportController (such as "disconnected").
1652   if (IsClosed()) {
1653     return;
1654   }
1655 
1656   RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1657                    << " => " << new_state;
1658   RTC_DCHECK(ice_connection_state_ !=
1659              PeerConnectionInterface::kIceConnectionClosed);
1660 
1661   ice_connection_state_ = new_state;
1662   Observer()->OnIceConnectionChange(ice_connection_state_);
1663 }
1664 
SetStandardizedIceConnectionState(PeerConnectionInterface::IceConnectionState new_state)1665 void PeerConnection::SetStandardizedIceConnectionState(
1666     PeerConnectionInterface::IceConnectionState new_state) {
1667   if (standardized_ice_connection_state_ == new_state) {
1668     return;
1669   }
1670 
1671   if (IsClosed()) {
1672     return;
1673   }
1674 
1675   RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1676                    << standardized_ice_connection_state_ << " => " << new_state;
1677 
1678   standardized_ice_connection_state_ = new_state;
1679   Observer()->OnStandardizedIceConnectionChange(new_state);
1680 }
1681 
SetConnectionState(PeerConnectionInterface::PeerConnectionState new_state)1682 void PeerConnection::SetConnectionState(
1683     PeerConnectionInterface::PeerConnectionState new_state) {
1684   if (connection_state_ == new_state)
1685     return;
1686   if (IsClosed())
1687     return;
1688   connection_state_ = new_state;
1689   Observer()->OnConnectionChange(new_state);
1690 }
1691 
OnIceGatheringChange(PeerConnectionInterface::IceGatheringState new_state)1692 void PeerConnection::OnIceGatheringChange(
1693     PeerConnectionInterface::IceGatheringState new_state) {
1694   if (IsClosed()) {
1695     return;
1696   }
1697   ice_gathering_state_ = new_state;
1698   Observer()->OnIceGatheringChange(ice_gathering_state_);
1699 }
1700 
OnIceCandidate(std::unique_ptr<IceCandidateInterface> candidate)1701 void PeerConnection::OnIceCandidate(
1702     std::unique_ptr<IceCandidateInterface> candidate) {
1703   if (IsClosed()) {
1704     return;
1705   }
1706   ReportIceCandidateCollected(candidate->candidate());
1707   Observer()->OnIceCandidate(candidate.get());
1708 }
1709 
OnIceCandidateError(const std::string & address,int port,const std::string & url,int error_code,const std::string & error_text)1710 void PeerConnection::OnIceCandidateError(const std::string& address,
1711                                          int port,
1712                                          const std::string& url,
1713                                          int error_code,
1714                                          const std::string& error_text) {
1715   if (IsClosed()) {
1716     return;
1717   }
1718   Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
1719   // Leftover not to break wpt test during migration to the new API.
1720   Observer()->OnIceCandidateError(address + ":", url, error_code, error_text);
1721 }
1722 
OnIceCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)1723 void PeerConnection::OnIceCandidatesRemoved(
1724     const std::vector<cricket::Candidate>& candidates) {
1725   if (IsClosed()) {
1726     return;
1727   }
1728   Observer()->OnIceCandidatesRemoved(candidates);
1729 }
1730 
OnSelectedCandidatePairChanged(const cricket::CandidatePairChangeEvent & event)1731 void PeerConnection::OnSelectedCandidatePairChanged(
1732     const cricket::CandidatePairChangeEvent& event) {
1733   if (IsClosed()) {
1734     return;
1735   }
1736 
1737   if (event.selected_candidate_pair.local_candidate().type() ==
1738           LOCAL_PORT_TYPE &&
1739       event.selected_candidate_pair.remote_candidate().type() ==
1740           LOCAL_PORT_TYPE) {
1741     NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
1742   }
1743 
1744   Observer()->OnIceSelectedCandidatePairChanged(event);
1745 }
1746 
GetDataMid() const1747 absl::optional<std::string> PeerConnection::GetDataMid() const {
1748   RTC_DCHECK_RUN_ON(signaling_thread());
1749   switch (data_channel_type()) {
1750     case cricket::DCT_RTP:
1751       if (!data_channel_controller_.rtp_data_channel()) {
1752         return absl::nullopt;
1753       }
1754       return data_channel_controller_.rtp_data_channel()->content_name();
1755     case cricket::DCT_SCTP:
1756       return sctp_mid_s_;
1757     default:
1758       return absl::nullopt;
1759   }
1760 }
1761 
OnSctpDataChannelClosed(DataChannelInterface * channel)1762 void PeerConnection::OnSctpDataChannelClosed(DataChannelInterface* channel) {
1763   // Since data_channel_controller doesn't do signals, this
1764   // signal is relayed here.
1765   data_channel_controller_.OnSctpDataChannelClosed(
1766       static_cast<SctpDataChannel*>(channel));
1767 }
1768 
FindDataChannelBySid(int sid) const1769 SctpDataChannel* PeerConnection::FindDataChannelBySid(int sid) const {
1770   return data_channel_controller_.FindDataChannelBySid(sid);
1771 }
1772 
1773 PeerConnection::InitializePortAllocatorResult
InitializePortAllocator_n(const cricket::ServerAddresses & stun_servers,const std::vector<cricket::RelayServerConfig> & turn_servers,const RTCConfiguration & configuration)1774 PeerConnection::InitializePortAllocator_n(
1775     const cricket::ServerAddresses& stun_servers,
1776     const std::vector<cricket::RelayServerConfig>& turn_servers,
1777     const RTCConfiguration& configuration) {
1778   RTC_DCHECK_RUN_ON(network_thread());
1779 
1780   port_allocator_->Initialize();
1781   // To handle both internal and externally created port allocator, we will
1782   // enable BUNDLE here.
1783   int port_allocator_flags = port_allocator_->flags();
1784   port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
1785                           cricket::PORTALLOCATOR_ENABLE_IPV6 |
1786                           cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
1787   // If the disable-IPv6 flag was specified, we'll not override it
1788   // by experiment.
1789   if (configuration.disable_ipv6) {
1790     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
1791   } else if (absl::StartsWith(context_->trials().Lookup("WebRTC-IPv6Default"),
1792                               "Disabled")) {
1793     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
1794   }
1795   if (configuration.disable_ipv6_on_wifi) {
1796     port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
1797     RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
1798   }
1799 
1800   if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
1801     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
1802     RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
1803   }
1804 
1805   if (configuration.candidate_network_policy ==
1806       kCandidateNetworkPolicyLowCost) {
1807     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
1808     RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
1809   }
1810 
1811   if (configuration.disable_link_local_networks) {
1812     port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
1813     RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
1814   }
1815 
1816   port_allocator_->set_flags(port_allocator_flags);
1817   // No step delay is used while allocating ports.
1818   port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
1819   port_allocator_->SetCandidateFilter(
1820       ConvertIceTransportTypeToCandidateFilter(configuration.type));
1821   port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
1822 
1823   auto turn_servers_copy = turn_servers;
1824   for (auto& turn_server : turn_servers_copy) {
1825     turn_server.tls_cert_verifier = tls_cert_verifier_.get();
1826   }
1827   // Call this last since it may create pooled allocator sessions using the
1828   // properties set above.
1829   port_allocator_->SetConfiguration(
1830       stun_servers, std::move(turn_servers_copy),
1831       configuration.ice_candidate_pool_size,
1832       configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
1833       configuration.stun_candidate_keepalive_interval);
1834 
1835   InitializePortAllocatorResult res;
1836   res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
1837   return res;
1838 }
1839 
ReconfigurePortAllocator_n(const cricket::ServerAddresses & stun_servers,const std::vector<cricket::RelayServerConfig> & turn_servers,IceTransportsType type,int candidate_pool_size,PortPrunePolicy turn_port_prune_policy,webrtc::TurnCustomizer * turn_customizer,absl::optional<int> stun_candidate_keepalive_interval,bool have_local_description)1840 bool PeerConnection::ReconfigurePortAllocator_n(
1841     const cricket::ServerAddresses& stun_servers,
1842     const std::vector<cricket::RelayServerConfig>& turn_servers,
1843     IceTransportsType type,
1844     int candidate_pool_size,
1845     PortPrunePolicy turn_port_prune_policy,
1846     webrtc::TurnCustomizer* turn_customizer,
1847     absl::optional<int> stun_candidate_keepalive_interval,
1848     bool have_local_description) {
1849   RTC_DCHECK_RUN_ON(network_thread());
1850   port_allocator_->SetCandidateFilter(
1851       ConvertIceTransportTypeToCandidateFilter(type));
1852   // According to JSEP, after setLocalDescription, changing the candidate pool
1853   // size is not allowed, and changing the set of ICE servers will not result
1854   // in new candidates being gathered.
1855   if (have_local_description) {
1856     port_allocator_->FreezeCandidatePool();
1857   }
1858   // Add the custom tls turn servers if they exist.
1859   auto turn_servers_copy = turn_servers;
1860   for (auto& turn_server : turn_servers_copy) {
1861     turn_server.tls_cert_verifier = tls_cert_verifier_.get();
1862   }
1863   // Call this last since it may create pooled allocator sessions using the
1864   // candidate filter set above.
1865   return port_allocator_->SetConfiguration(
1866       stun_servers, std::move(turn_servers_copy), candidate_pool_size,
1867       turn_port_prune_policy, turn_customizer,
1868       stun_candidate_keepalive_interval);
1869 }
1870 
channel_manager() const1871 cricket::ChannelManager* PeerConnection::channel_manager() const {
1872   return context_->channel_manager();
1873 }
1874 
StartRtcEventLog_w(std::unique_ptr<RtcEventLogOutput> output,int64_t output_period_ms)1875 bool PeerConnection::StartRtcEventLog_w(
1876     std::unique_ptr<RtcEventLogOutput> output,
1877     int64_t output_period_ms) {
1878   RTC_DCHECK_RUN_ON(worker_thread());
1879   if (!event_log_) {
1880     return false;
1881   }
1882   return event_log_->StartLogging(std::move(output), output_period_ms);
1883 }
1884 
StopRtcEventLog_w()1885 void PeerConnection::StopRtcEventLog_w() {
1886   RTC_DCHECK_RUN_ON(worker_thread());
1887   if (event_log_) {
1888     event_log_->StopLogging();
1889   }
1890 }
1891 
GetChannel(const std::string & content_name)1892 cricket::ChannelInterface* PeerConnection::GetChannel(
1893     const std::string& content_name) {
1894   for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1895     cricket::ChannelInterface* channel = transceiver->internal()->channel();
1896     if (channel && channel->content_name() == content_name) {
1897       return channel;
1898     }
1899   }
1900   if (rtp_data_channel() &&
1901       rtp_data_channel()->content_name() == content_name) {
1902     return rtp_data_channel();
1903   }
1904   return nullptr;
1905 }
1906 
GetSctpSslRole(rtc::SSLRole * role)1907 bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) {
1908   RTC_DCHECK_RUN_ON(signaling_thread());
1909   if (!local_description() || !remote_description()) {
1910     RTC_LOG(LS_VERBOSE)
1911         << "Local and Remote descriptions must be applied to get the "
1912            "SSL Role of the SCTP transport.";
1913     return false;
1914   }
1915   if (!data_channel_controller_.data_channel_transport()) {
1916     RTC_LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the "
1917                         "SSL Role of the SCTP transport.";
1918     return false;
1919   }
1920 
1921   absl::optional<rtc::SSLRole> dtls_role;
1922   if (sctp_mid_s_) {
1923     dtls_role = transport_controller_->GetDtlsRole(*sctp_mid_s_);
1924     if (!dtls_role && sdp_handler_->is_caller().has_value()) {
1925       dtls_role =
1926           *sdp_handler_->is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT;
1927     }
1928     *role = *dtls_role;
1929     return true;
1930   }
1931   return false;
1932 }
1933 
GetSslRole(const std::string & content_name,rtc::SSLRole * role)1934 bool PeerConnection::GetSslRole(const std::string& content_name,
1935                                 rtc::SSLRole* role) {
1936   RTC_DCHECK_RUN_ON(signaling_thread());
1937   if (!local_description() || !remote_description()) {
1938     RTC_LOG(LS_INFO)
1939         << "Local and Remote descriptions must be applied to get the "
1940            "SSL Role of the session.";
1941     return false;
1942   }
1943 
1944   auto dtls_role = transport_controller_->GetDtlsRole(content_name);
1945   if (dtls_role) {
1946     *role = *dtls_role;
1947     return true;
1948   }
1949   return false;
1950 }
1951 
GetTransportDescription(const SessionDescription * description,const std::string & content_name,cricket::TransportDescription * tdesc)1952 bool PeerConnection::GetTransportDescription(
1953     const SessionDescription* description,
1954     const std::string& content_name,
1955     cricket::TransportDescription* tdesc) {
1956   if (!description || !tdesc) {
1957     return false;
1958   }
1959   const TransportInfo* transport_info =
1960       description->GetTransportInfoByName(content_name);
1961   if (!transport_info) {
1962     return false;
1963   }
1964   *tdesc = transport_info->description;
1965   return true;
1966 }
1967 
GetDataChannelStats() const1968 std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
1969   RTC_DCHECK_RUN_ON(signaling_thread());
1970   return data_channel_controller_.GetDataChannelStats();
1971 }
1972 
sctp_transport_name() const1973 absl::optional<std::string> PeerConnection::sctp_transport_name() const {
1974   RTC_DCHECK_RUN_ON(signaling_thread());
1975   if (sctp_mid_s_ && transport_controller_) {
1976     auto dtls_transport = transport_controller_->GetDtlsTransport(*sctp_mid_s_);
1977     if (dtls_transport) {
1978       return dtls_transport->transport_name();
1979     }
1980     return absl::optional<std::string>();
1981   }
1982   return absl::optional<std::string>();
1983 }
1984 
GetPooledCandidateStats() const1985 cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
1986   cricket::CandidateStatsList candidate_states_list;
1987   network_thread()->Invoke<void>(
1988       RTC_FROM_HERE,
1989       rtc::Bind(&cricket::PortAllocator::GetCandidateStatsFromPooledSessions,
1990                 port_allocator_.get(), &candidate_states_list));
1991   return candidate_states_list;
1992 }
1993 
GetTransportNamesByMid() const1994 std::map<std::string, std::string> PeerConnection::GetTransportNamesByMid()
1995     const {
1996   RTC_DCHECK_RUN_ON(signaling_thread());
1997   std::map<std::string, std::string> transport_names_by_mid;
1998   for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1999     cricket::ChannelInterface* channel = transceiver->internal()->channel();
2000     if (channel) {
2001       transport_names_by_mid[channel->content_name()] =
2002           channel->transport_name();
2003     }
2004   }
2005   if (data_channel_controller_.rtp_data_channel()) {
2006     transport_names_by_mid[data_channel_controller_.rtp_data_channel()
2007                                ->content_name()] =
2008         data_channel_controller_.rtp_data_channel()->transport_name();
2009   }
2010   if (data_channel_controller_.data_channel_transport()) {
2011     absl::optional<std::string> transport_name = sctp_transport_name();
2012     RTC_DCHECK(transport_name);
2013     transport_names_by_mid[*sctp_mid_s_] = *transport_name;
2014   }
2015   return transport_names_by_mid;
2016 }
2017 
2018 std::map<std::string, cricket::TransportStats>
GetTransportStatsByNames(const std::set<std::string> & transport_names)2019 PeerConnection::GetTransportStatsByNames(
2020     const std::set<std::string>& transport_names) {
2021   if (!network_thread()->IsCurrent()) {
2022     return network_thread()
2023         ->Invoke<std::map<std::string, cricket::TransportStats>>(
2024             RTC_FROM_HERE,
2025             [&] { return GetTransportStatsByNames(transport_names); });
2026   }
2027   RTC_DCHECK_RUN_ON(network_thread());
2028   std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2029   for (const std::string& transport_name : transport_names) {
2030     cricket::TransportStats transport_stats;
2031     bool success =
2032         transport_controller_->GetStats(transport_name, &transport_stats);
2033     if (success) {
2034       transport_stats_by_name[transport_name] = std::move(transport_stats);
2035     } else {
2036       RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2037                         << transport_name;
2038     }
2039   }
2040   return transport_stats_by_name;
2041 }
2042 
GetLocalCertificate(const std::string & transport_name,rtc::scoped_refptr<rtc::RTCCertificate> * certificate)2043 bool PeerConnection::GetLocalCertificate(
2044     const std::string& transport_name,
2045     rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
2046   if (!certificate) {
2047     return false;
2048   }
2049   *certificate = transport_controller_->GetLocalCertificate(transport_name);
2050   return *certificate != nullptr;
2051 }
2052 
GetRemoteSSLCertChain(const std::string & transport_name)2053 std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
2054     const std::string& transport_name) {
2055   return transport_controller_->GetRemoteSSLCertChain(transport_name);
2056 }
2057 
data_channel_type() const2058 cricket::DataChannelType PeerConnection::data_channel_type() const {
2059   return data_channel_controller_.data_channel_type();
2060 }
2061 
IceRestartPending(const std::string & content_name) const2062 bool PeerConnection::IceRestartPending(const std::string& content_name) const {
2063   RTC_DCHECK_RUN_ON(signaling_thread());
2064   return sdp_handler_->IceRestartPending(content_name);
2065 }
2066 
NeedsIceRestart(const std::string & content_name) const2067 bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
2068   return transport_controller_->NeedsIceRestart(content_name);
2069 }
2070 
OnTransportControllerConnectionState(cricket::IceConnectionState state)2071 void PeerConnection::OnTransportControllerConnectionState(
2072     cricket::IceConnectionState state) {
2073   switch (state) {
2074     case cricket::kIceConnectionConnecting:
2075       // If the current state is Connected or Completed, then there were
2076       // writable channels but now there are not, so the next state must
2077       // be Disconnected.
2078       // kIceConnectionConnecting is currently used as the default,
2079       // un-connected state by the TransportController, so its only use is
2080       // detecting disconnections.
2081       if (ice_connection_state_ ==
2082               PeerConnectionInterface::kIceConnectionConnected ||
2083           ice_connection_state_ ==
2084               PeerConnectionInterface::kIceConnectionCompleted) {
2085         SetIceConnectionState(
2086             PeerConnectionInterface::kIceConnectionDisconnected);
2087       }
2088       break;
2089     case cricket::kIceConnectionFailed:
2090       SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2091       break;
2092     case cricket::kIceConnectionConnected:
2093       RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2094                           "all transports are writable.";
2095       SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2096       NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2097       break;
2098     case cricket::kIceConnectionCompleted:
2099       RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2100                           "all transports are complete.";
2101       if (ice_connection_state_ !=
2102           PeerConnectionInterface::kIceConnectionConnected) {
2103         // If jumping directly from "checking" to "connected",
2104         // signal "connected" first.
2105         SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2106       }
2107       SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
2108       NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2109       ReportTransportStats();
2110       break;
2111     default:
2112       RTC_NOTREACHED();
2113   }
2114 }
2115 
OnTransportControllerCandidatesGathered(const std::string & transport_name,const cricket::Candidates & candidates)2116 void PeerConnection::OnTransportControllerCandidatesGathered(
2117     const std::string& transport_name,
2118     const cricket::Candidates& candidates) {
2119   int sdp_mline_index;
2120   if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
2121     RTC_LOG(LS_ERROR)
2122         << "OnTransportControllerCandidatesGathered: content name "
2123         << transport_name << " not found";
2124     return;
2125   }
2126 
2127   for (cricket::Candidates::const_iterator citer = candidates.begin();
2128        citer != candidates.end(); ++citer) {
2129     // Use transport_name as the candidate media id.
2130     std::unique_ptr<JsepIceCandidate> candidate(
2131         new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
2132     sdp_handler_->AddLocalIceCandidate(candidate.get());
2133     OnIceCandidate(std::move(candidate));
2134   }
2135 }
2136 
OnTransportControllerCandidateError(const cricket::IceCandidateErrorEvent & event)2137 void PeerConnection::OnTransportControllerCandidateError(
2138     const cricket::IceCandidateErrorEvent& event) {
2139   OnIceCandidateError(event.address, event.port, event.url, event.error_code,
2140                       event.error_text);
2141 }
2142 
OnTransportControllerCandidatesRemoved(const std::vector<cricket::Candidate> & candidates)2143 void PeerConnection::OnTransportControllerCandidatesRemoved(
2144     const std::vector<cricket::Candidate>& candidates) {
2145   // Sanity check.
2146   for (const cricket::Candidate& candidate : candidates) {
2147     if (candidate.transport_name().empty()) {
2148       RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
2149                            "empty content name in candidate "
2150                         << candidate.ToString();
2151       return;
2152     }
2153   }
2154   sdp_handler_->RemoveLocalIceCandidates(candidates);
2155   OnIceCandidatesRemoved(candidates);
2156 }
2157 
OnTransportControllerCandidateChanged(const cricket::CandidatePairChangeEvent & event)2158 void PeerConnection::OnTransportControllerCandidateChanged(
2159     const cricket::CandidatePairChangeEvent& event) {
2160   OnSelectedCandidatePairChanged(event);
2161 }
2162 
OnTransportControllerDtlsHandshakeError(rtc::SSLHandshakeError error)2163 void PeerConnection::OnTransportControllerDtlsHandshakeError(
2164     rtc::SSLHandshakeError error) {
2165   RTC_HISTOGRAM_ENUMERATION(
2166       "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2167       static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
2168 }
2169 
2170 // Returns the media index for a local ice candidate given the content name.
GetLocalCandidateMediaIndex(const std::string & content_name,int * sdp_mline_index)2171 bool PeerConnection::GetLocalCandidateMediaIndex(
2172     const std::string& content_name,
2173     int* sdp_mline_index) {
2174   if (!local_description() || !sdp_mline_index) {
2175     return false;
2176   }
2177 
2178   bool content_found = false;
2179   const ContentInfos& contents = local_description()->description()->contents();
2180   for (size_t index = 0; index < contents.size(); ++index) {
2181     if (contents[index].name == content_name) {
2182       *sdp_mline_index = static_cast<int>(index);
2183       content_found = true;
2184       break;
2185     }
2186   }
2187   return content_found;
2188 }
2189 
GetCallStats()2190 Call::Stats PeerConnection::GetCallStats() {
2191   if (!worker_thread()->IsCurrent()) {
2192     return worker_thread()->Invoke<Call::Stats>(
2193         RTC_FROM_HERE, rtc::Bind(&PeerConnection::GetCallStats, this));
2194   }
2195   RTC_DCHECK_RUN_ON(worker_thread());
2196   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
2197   if (call_) {
2198     return call_->GetStats();
2199   } else {
2200     return Call::Stats();
2201   }
2202 }
2203 
SetupDataChannelTransport_n(const std::string & mid)2204 bool PeerConnection::SetupDataChannelTransport_n(const std::string& mid) {
2205   DataChannelTransportInterface* transport =
2206       transport_controller_->GetDataChannelTransport(mid);
2207   if (!transport) {
2208     RTC_LOG(LS_ERROR)
2209         << "Data channel transport is not available for data channels, mid="
2210         << mid;
2211     return false;
2212   }
2213   RTC_LOG(LS_INFO) << "Setting up data channel transport for mid=" << mid;
2214 
2215   data_channel_controller_.set_data_channel_transport(transport);
2216   data_channel_controller_.SetupDataChannelTransport_n();
2217   sctp_mid_n_ = mid;
2218 
2219   // Note: setting the data sink and checking initial state must be done last,
2220   // after setting up the data channel.  Setting the data sink may trigger
2221   // callbacks to PeerConnection which require the transport to be completely
2222   // set up (eg. OnReadyToSend()).
2223   transport->SetDataSink(&data_channel_controller_);
2224   return true;
2225 }
2226 
TeardownDataChannelTransport_n()2227 void PeerConnection::TeardownDataChannelTransport_n() {
2228   if (!sctp_mid_n_ && !data_channel_controller_.data_channel_transport()) {
2229     return;
2230   }
2231   RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2232                    << *sctp_mid_n_;
2233 
2234   // |sctp_mid_| may still be active through an SCTP transport.  If not, unset
2235   // it.
2236   sctp_mid_n_.reset();
2237   data_channel_controller_.TeardownDataChannelTransport_n();
2238 }
2239 
2240 // Returns false if bundle is enabled and rtcp_mux is disabled.
ValidateBundleSettings(const SessionDescription * desc)2241 bool PeerConnection::ValidateBundleSettings(const SessionDescription* desc) {
2242   bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2243   if (!bundle_enabled)
2244     return true;
2245 
2246   const cricket::ContentGroup* bundle_group =
2247       desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
2248   RTC_DCHECK(bundle_group != NULL);
2249 
2250   const cricket::ContentInfos& contents = desc->contents();
2251   for (cricket::ContentInfos::const_iterator citer = contents.begin();
2252        citer != contents.end(); ++citer) {
2253     const cricket::ContentInfo* content = (&*citer);
2254     RTC_DCHECK(content != NULL);
2255     if (bundle_group->HasContentName(content->name) && !content->rejected &&
2256         content->type == MediaProtocolType::kRtp) {
2257       if (!HasRtcpMuxEnabled(content))
2258         return false;
2259     }
2260   }
2261   // RTCP-MUX is enabled in all the contents.
2262   return true;
2263 }
2264 
ReportSdpFormatReceived(const SessionDescriptionInterface & remote_offer)2265 void PeerConnection::ReportSdpFormatReceived(
2266     const SessionDescriptionInterface& remote_offer) {
2267   int num_audio_mlines = 0;
2268   int num_video_mlines = 0;
2269   int num_audio_tracks = 0;
2270   int num_video_tracks = 0;
2271   for (const ContentInfo& content : remote_offer.description()->contents()) {
2272     cricket::MediaType media_type = content.media_description()->type();
2273     int num_tracks = std::max(
2274         1, static_cast<int>(content.media_description()->streams().size()));
2275     if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2276       num_audio_mlines += 1;
2277       num_audio_tracks += num_tracks;
2278     } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2279       num_video_mlines += 1;
2280       num_video_tracks += num_tracks;
2281     }
2282   }
2283   SdpFormatReceived format = kSdpFormatReceivedNoTracks;
2284   if (num_audio_mlines > 1 || num_video_mlines > 1) {
2285     format = kSdpFormatReceivedComplexUnifiedPlan;
2286   } else if (num_audio_tracks > 1 || num_video_tracks > 1) {
2287     format = kSdpFormatReceivedComplexPlanB;
2288   } else if (num_audio_tracks > 0 || num_video_tracks > 0) {
2289     format = kSdpFormatReceivedSimple;
2290   }
2291   switch (remote_offer.GetType()) {
2292     case SdpType::kOffer:
2293       // Historically only offers were counted.
2294       RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceived",
2295                                 format, kSdpFormatReceivedMax);
2296       break;
2297     case SdpType::kAnswer:
2298       RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpFormatReceivedAnswer",
2299                                 format, kSdpFormatReceivedMax);
2300       break;
2301     default:
2302       RTC_LOG(LS_ERROR) << "Can not report SdpFormatReceived for "
2303                         << SdpTypeToString(remote_offer.GetType());
2304       break;
2305   }
2306 }
2307 
ReportIceCandidateCollected(const cricket::Candidate & candidate)2308 void PeerConnection::ReportIceCandidateCollected(
2309     const cricket::Candidate& candidate) {
2310   NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2311   if (candidate.address().IsPrivateIP()) {
2312     NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2313   }
2314   if (candidate.address().IsUnresolvedIP()) {
2315     NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2316   }
2317   if (candidate.address().family() == AF_INET6) {
2318     NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2319   }
2320 }
2321 
NoteUsageEvent(UsageEvent event)2322 void PeerConnection::NoteUsageEvent(UsageEvent event) {
2323   RTC_DCHECK_RUN_ON(signaling_thread());
2324   usage_pattern_.NoteUsageEvent(event);
2325 }
2326 
ReportUsagePattern() const2327 void PeerConnection::ReportUsagePattern() const {
2328   usage_pattern_.ReportUsagePattern(observer_);
2329 }
2330 
SrtpRequired() const2331 bool PeerConnection::SrtpRequired() const {
2332   return (dtls_enabled_ ||
2333           sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2334               cricket::SEC_REQUIRED);
2335 }
2336 
OnTransportControllerGatheringState(cricket::IceGatheringState state)2337 void PeerConnection::OnTransportControllerGatheringState(
2338     cricket::IceGatheringState state) {
2339   RTC_DCHECK(signaling_thread()->IsCurrent());
2340   if (state == cricket::kIceGatheringGathering) {
2341     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2342   } else if (state == cricket::kIceGatheringComplete) {
2343     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
2344   } else if (state == cricket::kIceGatheringNew) {
2345     OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2346   } else {
2347     RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
2348     RTC_NOTREACHED();
2349   }
2350 }
2351 
ReportTransportStats()2352 void PeerConnection::ReportTransportStats() {
2353   std::map<std::string, std::set<cricket::MediaType>>
2354       media_types_by_transport_name;
2355   for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
2356     if (transceiver->internal()->channel()) {
2357       const std::string& transport_name =
2358           transceiver->internal()->channel()->transport_name();
2359       media_types_by_transport_name[transport_name].insert(
2360           transceiver->media_type());
2361     }
2362   }
2363   if (rtp_data_channel()) {
2364     media_types_by_transport_name[rtp_data_channel()->transport_name()].insert(
2365         cricket::MEDIA_TYPE_DATA);
2366   }
2367 
2368   absl::optional<std::string> transport_name = sctp_transport_name();
2369   if (transport_name) {
2370     media_types_by_transport_name[*transport_name].insert(
2371         cricket::MEDIA_TYPE_DATA);
2372   }
2373 
2374   for (const auto& entry : media_types_by_transport_name) {
2375     const std::string& transport_name = entry.first;
2376     const std::set<cricket::MediaType> media_types = entry.second;
2377     cricket::TransportStats stats;
2378     if (transport_controller_->GetStats(transport_name, &stats)) {
2379       ReportBestConnectionState(stats);
2380       ReportNegotiatedCiphers(stats, media_types);
2381     }
2382   }
2383 }
2384 // Walk through the ConnectionInfos to gather best connection usage
2385 // for IPv4 and IPv6.
ReportBestConnectionState(const cricket::TransportStats & stats)2386 void PeerConnection::ReportBestConnectionState(
2387     const cricket::TransportStats& stats) {
2388   for (const cricket::TransportChannelStats& channel_stats :
2389        stats.channel_stats) {
2390     for (const cricket::ConnectionInfo& connection_info :
2391          channel_stats.ice_transport_stats.connection_infos) {
2392       if (!connection_info.best_connection) {
2393         continue;
2394       }
2395 
2396       const cricket::Candidate& local = connection_info.local_candidate;
2397       const cricket::Candidate& remote = connection_info.remote_candidate;
2398 
2399       // Increment the counter for IceCandidatePairType.
2400       if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
2401           (local.type() == RELAY_PORT_TYPE &&
2402            local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
2403         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2404                                   GetIceCandidatePairCounter(local, remote),
2405                                   kIceCandidatePairMax);
2406       } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
2407         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2408                                   GetIceCandidatePairCounter(local, remote),
2409                                   kIceCandidatePairMax);
2410       } else {
2411         RTC_CHECK_NOTREACHED();
2412       }
2413 
2414       // Increment the counter for IP type.
2415       if (local.address().family() == AF_INET) {
2416         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2417                                   kBestConnections_IPv4,
2418                                   kPeerConnectionAddressFamilyCounter_Max);
2419       } else if (local.address().family() == AF_INET6) {
2420         RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2421                                   kBestConnections_IPv6,
2422                                   kPeerConnectionAddressFamilyCounter_Max);
2423       } else {
2424         RTC_CHECK(!local.address().hostname().empty() &&
2425                   local.address().IsUnresolvedIP());
2426       }
2427 
2428       return;
2429     }
2430   }
2431 }
2432 
ReportNegotiatedCiphers(const cricket::TransportStats & stats,const std::set<cricket::MediaType> & media_types)2433 void PeerConnection::ReportNegotiatedCiphers(
2434     const cricket::TransportStats& stats,
2435     const std::set<cricket::MediaType>& media_types) {
2436   if (!dtls_enabled_ || stats.channel_stats.empty()) {
2437     return;
2438   }
2439 
2440   int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2441   int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
2442   if (srtp_crypto_suite == rtc::SRTP_INVALID_CRYPTO_SUITE &&
2443       ssl_cipher_suite == rtc::TLS_NULL_WITH_NULL_NULL) {
2444     return;
2445   }
2446 
2447   if (srtp_crypto_suite != rtc::SRTP_INVALID_CRYPTO_SUITE) {
2448     for (cricket::MediaType media_type : media_types) {
2449       switch (media_type) {
2450         case cricket::MEDIA_TYPE_AUDIO:
2451           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2452               "WebRTC.PeerConnection.SrtpCryptoSuite.Audio", srtp_crypto_suite,
2453               rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2454           break;
2455         case cricket::MEDIA_TYPE_VIDEO:
2456           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2457               "WebRTC.PeerConnection.SrtpCryptoSuite.Video", srtp_crypto_suite,
2458               rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2459           break;
2460         case cricket::MEDIA_TYPE_DATA:
2461           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2462               "WebRTC.PeerConnection.SrtpCryptoSuite.Data", srtp_crypto_suite,
2463               rtc::SRTP_CRYPTO_SUITE_MAX_VALUE);
2464           break;
2465         default:
2466           RTC_NOTREACHED();
2467           continue;
2468       }
2469     }
2470   }
2471 
2472   if (ssl_cipher_suite != rtc::TLS_NULL_WITH_NULL_NULL) {
2473     for (cricket::MediaType media_type : media_types) {
2474       switch (media_type) {
2475         case cricket::MEDIA_TYPE_AUDIO:
2476           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2477               "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
2478               rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2479           break;
2480         case cricket::MEDIA_TYPE_VIDEO:
2481           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2482               "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
2483               rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2484           break;
2485         case cricket::MEDIA_TYPE_DATA:
2486           RTC_HISTOGRAM_ENUMERATION_SPARSE(
2487               "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
2488               rtc::SSL_CIPHER_SUITE_MAX_VALUE);
2489           break;
2490         default:
2491           RTC_NOTREACHED();
2492           continue;
2493       }
2494     }
2495   }
2496 }
2497 
OnSentPacket_w(const rtc::SentPacket & sent_packet)2498 void PeerConnection::OnSentPacket_w(const rtc::SentPacket& sent_packet) {
2499   RTC_DCHECK_RUN_ON(worker_thread());
2500   RTC_DCHECK(call_);
2501   call_->OnSentPacket(sent_packet);
2502 }
2503 
OnTransportChanged(const std::string & mid,RtpTransportInternal * rtp_transport,rtc::scoped_refptr<DtlsTransport> dtls_transport,DataChannelTransportInterface * data_channel_transport)2504 bool PeerConnection::OnTransportChanged(
2505     const std::string& mid,
2506     RtpTransportInternal* rtp_transport,
2507     rtc::scoped_refptr<DtlsTransport> dtls_transport,
2508     DataChannelTransportInterface* data_channel_transport) {
2509   RTC_DCHECK_RUN_ON(network_thread());
2510   bool ret = true;
2511   auto base_channel = GetChannel(mid);
2512   if (base_channel) {
2513     ret = base_channel->SetRtpTransport(rtp_transport);
2514   }
2515   if (mid == sctp_mid_n_) {
2516     data_channel_controller_.OnTransportChanged(data_channel_transport);
2517   }
2518   return ret;
2519 }
2520 
Observer() const2521 PeerConnectionObserver* PeerConnection::Observer() const {
2522   RTC_DCHECK_RUN_ON(signaling_thread());
2523   RTC_DCHECK(observer_);
2524   return observer_;
2525 }
2526 
GetCryptoOptions()2527 CryptoOptions PeerConnection::GetCryptoOptions() {
2528   RTC_DCHECK_RUN_ON(signaling_thread());
2529   // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2530   // after it has been removed.
2531   return configuration_.crypto_options.has_value()
2532              ? *configuration_.crypto_options
2533              : options_.crypto_options;
2534 }
2535 
ClearStatsCache()2536 void PeerConnection::ClearStatsCache() {
2537   RTC_DCHECK_RUN_ON(signaling_thread());
2538   if (stats_collector_) {
2539     stats_collector_->ClearCachedStatsReport();
2540   }
2541 }
2542 
ShouldFireNegotiationNeededEvent(uint32_t event_id)2543 bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2544   RTC_DCHECK_RUN_ON(signaling_thread());
2545   return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
2546 }
2547 
RequestUsagePatternReportForTesting()2548 void PeerConnection::RequestUsagePatternReportForTesting() {
2549   message_handler_.RequestUsagePatternReport(
2550       [this]() {
2551         RTC_DCHECK_RUN_ON(signaling_thread());
2552         ReportUsagePattern();
2553       },
2554       /* delay_ms= */ 0);
2555 }
2556 
2557 std::function<void(const rtc::CopyOnWriteBuffer& packet,
2558                    int64_t packet_time_us)>
InitializeRtcpCallback()2559 PeerConnection::InitializeRtcpCallback() {
2560   RTC_DCHECK_RUN_ON(signaling_thread());
2561 
2562   auto flag =
2563       worker_thread()->Invoke<rtc::scoped_refptr<PendingTaskSafetyFlag>>(
2564           RTC_FROM_HERE, [this] {
2565             RTC_DCHECK_RUN_ON(worker_thread());
2566             if (!call_)
2567               return rtc::scoped_refptr<PendingTaskSafetyFlag>();
2568             if (!call_safety_)
2569               call_safety_.reset(new ScopedTaskSafety());
2570             return call_safety_->flag();
2571           });
2572 
2573   if (!flag)
2574     return [](const rtc::CopyOnWriteBuffer&, int64_t) {};
2575 
2576   return [this, flag = std::move(flag)](const rtc::CopyOnWriteBuffer& packet,
2577                                         int64_t packet_time_us) {
2578     RTC_DCHECK_RUN_ON(network_thread());
2579     // TODO(bugs.webrtc.org/11993): We should actually be delivering this call
2580     // directly to the Call class somehow directly on the network thread and not
2581     // incur this hop here. The DeliverPacket() method will eventually just have
2582     // to hop back over to the network thread.
2583     worker_thread()->PostTask(ToQueuedTask(flag, [this, packet,
2584                                                   packet_time_us] {
2585       RTC_DCHECK_RUN_ON(worker_thread());
2586       call_->Receiver()->DeliverPacket(MediaType::ANY, packet, packet_time_us);
2587     }));
2588   };
2589 }
2590 
2591 }  // namespace webrtc
2592