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