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