blob: 24242acaddbdecc44f636f8daac68edfda583109 [file] [log] [blame]
hjonf396f602016-02-11 16:19:06 -08001/*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCPeerConnection+Private.h"
12
tkchin9eeb6242016-04-27 01:54:20 -070013#import "RTCConfiguration+Private.h"
14#import "RTCDataChannel+Private.h"
15#import "RTCIceCandidate+Private.h"
Jaehyun Kod2110982021-11-30 19:01:43 +090016#import "RTCIceCandidateErrorEvent+Private.h"
hbosbd3dda62016-09-09 01:36:28 -070017#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCMediaConstraints+Private.h"
19#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080020#import "RTCMediaStreamTrack+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070021#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070022#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070023#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080024#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070025#import "RTCSessionDescription+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020026#import "base/RTCLogging.h"
27#import "helpers/NSString+StdString.h"
hjonf396f602016-02-11 16:19:06 -080028
kwibergbfefb032016-05-01 14:53:46 -070029#include <memory>
30
Steve Anton10542f22019-01-11 09:11:00 -080031#include "api/jsep_ice_candidate.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020032#include "api/rtc_event_log_output_file.h"
Yura Yaroshevichd6725352021-03-05 18:21:16 +030033#include "api/set_local_description_observer_interface.h"
34#include "api/set_remote_description_observer_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/checks.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020036#include "rtc_base/numerics/safe_conversions.h"
hjonf396f602016-02-11 16:19:06 -080037
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020038NSString *const kRTCPeerConnectionErrorDomain = @"org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection)";
hjonf396f602016-02-11 16:19:06 -080039int const kRTCPeerConnnectionSessionDescriptionError = -1;
40
Yura Yaroshevichd6725352021-03-05 18:21:16 +030041namespace {
42
43class SetSessionDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface,
44 public webrtc::SetRemoteDescriptionObserverInterface {
45 public:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030046 SetSessionDescriptionObserver(RTCSetSessionDescriptionCompletionHandler completionHandler) {
Yura Yaroshevichd6725352021-03-05 18:21:16 +030047 completion_handler_ = completionHandler;
48 }
49
50 virtual void OnSetLocalDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030051 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030052 }
53
54 virtual void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030055 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030056 }
57
58 private:
59 void OnCompelete(webrtc::RTCError error) {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030060 RTC_DCHECK(completion_handler_ != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030061 if (error.ok()) {
62 completion_handler_(nil);
63 } else {
64 // TODO(hta): Add handling of error.type()
65 NSString *str = [NSString stringForStdString:error.message()];
66 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
67 code:kRTCPeerConnnectionSessionDescriptionError
68 userInfo:@{NSLocalizedDescriptionKey : str}];
69 completion_handler_(err);
70 }
71 completion_handler_ = nil;
72 }
73 RTCSetSessionDescriptionCompletionHandler completion_handler_;
74};
75
76} // anonymous namespace
77
hjonf396f602016-02-11 16:19:06 -080078namespace webrtc {
79
80class CreateSessionDescriptionObserverAdapter
81 : public CreateSessionDescriptionObserver {
82 public:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020083 CreateSessionDescriptionObserverAdapter(void (^completionHandler)(
84 RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, NSError *error)) {
hjonf396f602016-02-11 16:19:06 -080085 completion_handler_ = completionHandler;
86 }
87
Mirko Bonadei17aff352018-07-26 12:20:40 +020088 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080089
90 void OnSuccess(SessionDescriptionInterface *desc) override {
91 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070092 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
93 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020094 RTC_OBJC_TYPE(RTCSessionDescription) *session =
95 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description.get()];
hjonf396f602016-02-11 16:19:06 -080096 completion_handler_(session, nil);
97 completion_handler_ = nil;
98 }
99
Harald Alvestrand73771a82018-05-24 10:53:49 +0200100 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -0800101 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200102 // TODO(hta): Add handling of error.type()
103 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800104 NSError* err =
105 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
106 code:kRTCPeerConnnectionSessionDescriptionError
107 userInfo:@{ NSLocalizedDescriptionKey : str }];
108 completion_handler_(nil, err);
109 completion_handler_ = nil;
110 }
111
112 private:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200113 void (^completion_handler_)(RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription,
114 NSError *error);
hjonf396f602016-02-11 16:19:06 -0800115};
116
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200117PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) *
118 peerConnection) {
hjonf396f602016-02-11 16:19:06 -0800119 peer_connection_ = peerConnection;
120}
121
122PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
123 peer_connection_ = nil;
124}
125
126void PeerConnectionDelegateAdapter::OnSignalingChange(
127 PeerConnectionInterface::SignalingState new_state) {
128 RTCSignalingState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200129 [[RTC_OBJC_TYPE(RTCPeerConnection) class] signalingStateForNativeState:new_state];
130 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800131 [peer_connection.delegate peerConnection:peer_connection
132 didChangeSignalingState:state];
133}
134
135void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700136 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200137 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
138 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
139 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
140 nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800141 [peer_connection.delegate peerConnection:peer_connection
142 didAddStream:mediaStream];
143}
144
145void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700146 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200147 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
148 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
149 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
150 nativeMediaStream:stream];
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300151
hjonf396f602016-02-11 16:19:06 -0800152 [peer_connection.delegate peerConnection:peer_connection
153 didRemoveStream:mediaStream];
154}
155
Steve Anton8cb344a2018-02-27 15:34:53 -0800156void PeerConnectionDelegateAdapter::OnTrack(
157 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200158 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
159 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
160 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:peer_connection.factory
161 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800162 if ([peer_connection.delegate
163 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
164 [peer_connection.delegate peerConnection:peer_connection
165 didStartReceivingOnTransceiver:transceiver];
166 }
167}
168
hjonf396f602016-02-11 16:19:06 -0800169void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700170 rtc::scoped_refptr<DataChannelInterface> data_channel) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200171 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
172 RTC_OBJC_TYPE(RTCDataChannel) *dataChannel =
173 [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:peer_connection.factory
174 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800175 [peer_connection.delegate peerConnection:peer_connection
176 didOpenDataChannel:dataChannel];
177}
178
179void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200180 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800181 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
182}
183
184void PeerConnectionDelegateAdapter::OnIceConnectionChange(
185 PeerConnectionInterface::IceConnectionState new_state) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200186 RTCIceConnectionState state =
187 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100188 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
189}
190
Qingsi Wang36e31472019-05-29 11:37:26 -0700191void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
192 PeerConnectionInterface::IceConnectionState new_state) {
193 if ([peer_connection_.delegate
194 respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200195 RTCIceConnectionState state =
196 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Qingsi Wang36e31472019-05-29 11:37:26 -0700197 [peer_connection_.delegate peerConnection:peer_connection_
198 didChangeStandardizedIceConnectionState:state];
199 }
200}
201
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100202void PeerConnectionDelegateAdapter::OnConnectionChange(
203 PeerConnectionInterface::PeerConnectionState new_state) {
204 if ([peer_connection_.delegate
205 respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200206 RTCPeerConnectionState state =
207 [RTC_OBJC_TYPE(RTCPeerConnection) connectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100208 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
209 }
hjonf396f602016-02-11 16:19:06 -0800210}
211
212void PeerConnectionDelegateAdapter::OnIceGatheringChange(
213 PeerConnectionInterface::IceGatheringState new_state) {
214 RTCIceGatheringState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200215 [[RTC_OBJC_TYPE(RTCPeerConnection) class] iceGatheringStateForNativeState:new_state];
216 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800217 [peer_connection.delegate peerConnection:peer_connection
218 didChangeIceGatheringState:state];
219}
220
221void PeerConnectionDelegateAdapter::OnIceCandidate(
222 const IceCandidateInterface *candidate) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200223 RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate =
224 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate];
225 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800226 [peer_connection.delegate peerConnection:peer_connection
227 didGenerateIceCandidate:iceCandidate];
228}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700229
Jaehyun Kod2110982021-11-30 19:01:43 +0900230void PeerConnectionDelegateAdapter::OnIceCandidateError(const std::string &address,
231 int port,
232 const std::string &url,
233 int error_code,
234 const std::string &error_text) {
235 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
236 RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event =
237 [[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc] initWithAddress:address
238 port:port
239 url:url
240 errorCode:error_code
241 errorText:error_text];
242 [peer_connection.delegate peerConnection:peer_connection didFailToGatherIceCandidate:event];
243}
244
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700245void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
246 const std::vector<cricket::Candidate>& candidates) {
247 NSMutableArray* ice_candidates =
248 [NSMutableArray arrayWithCapacity:candidates.size()];
249 for (const auto& candidate : candidates) {
250 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
251 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200252 RTC_OBJC_TYPE(RTCIceCandidate) *ice_candidate =
253 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate_wrapper.get()];
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700254 [ice_candidates addObject:ice_candidate];
255 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200256 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700257 [peer_connection.delegate peerConnection:peer_connection
258 didRemoveIceCandidates:ice_candidates];
259}
260
Alex Drake43faee02019-08-12 16:27:34 -0700261void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
262 const cricket::CandidatePairChangeEvent &event) {
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700263 const auto &selected_pair = event.selected_candidate_pair;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200264 auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700265 selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200266 RTC_OBJC_TYPE(RTCIceCandidate) *local_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
267 initWithNativeCandidate:local_candidate_wrapper.release()];
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200268 auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700269 selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200270 RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
271 initWithNativeCandidate:remote_candidate_wrapper.release()];
272 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Alex Drake43faee02019-08-12 16:27:34 -0700273 NSString *nsstr_reason = [NSString stringForStdString:event.reason];
274 if ([peer_connection.delegate
275 respondsToSelector:@selector
276 (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) {
277 [peer_connection.delegate peerConnection:peer_connection
278 didChangeLocalCandidate:local_candidate
279 remoteCandidate:remote_candidate
280 lastReceivedMs:event.last_data_received_ms
281 changeReason:nsstr_reason];
282 }
283}
284
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300285void PeerConnectionDelegateAdapter::OnAddTrack(
286 rtc::scoped_refptr<RtpReceiverInterface> receiver,
Alex Drake43faee02019-08-12 16:27:34 -0700287 const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200288 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Alex Drake43faee02019-08-12 16:27:34 -0700289 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
290 didAddReceiver:streams:)]) {
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300291 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
Alex Drake43faee02019-08-12 16:27:34 -0700292 for (const auto &nativeStream : streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200293 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
294 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
295 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300296 [mediaStreams addObject:mediaStream];
297 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200298 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
299 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
300 nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300301
302 [peer_connection.delegate peerConnection:peer_connection
303 didAddReceiver:rtpReceiver
304 streams:mediaStreams];
305 }
306}
307
Zeke Chin8de502b2018-08-21 11:41:07 -0700308void PeerConnectionDelegateAdapter::OnRemoveTrack(
309 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200310 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Zeke Chin8de502b2018-08-21 11:41:07 -0700311 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200312 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
313 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
314 nativeRtpReceiver:receiver];
Zeke Chin8de502b2018-08-21 11:41:07 -0700315 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
316 }
317}
318
hjonf396f602016-02-11 16:19:06 -0800319} // namespace webrtc
320
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200321@implementation RTC_OBJC_TYPE (RTCPeerConnection) {
322 RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
323 NSMutableArray<RTC_OBJC_TYPE(RTCMediaStream) *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700324 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800325 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800326 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700327 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800328}
329
330@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300331@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800332
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300333- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
334 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
335 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
336 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
hjonf396f602016-02-11 16:19:06 -0800337 NSParameterAssert(factory);
Jonas Oreland285f83d2020-02-07 10:30:08 +0100338 std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies =
339 std::make_unique<webrtc::PeerConnectionDependencies>(nullptr);
340 return [self initWithDependencies:factory
341 configuration:configuration
342 constraints:constraints
343 dependencies:std::move(dependencies)
344 delegate:delegate];
345}
346
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300347- (nullable instancetype)
348 initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
349 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
350 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
351 dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies
352 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
Jonas Oreland285f83d2020-02-07 10:30:08 +0100353 NSParameterAssert(factory);
354 NSParameterAssert(dependencies.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200355 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700356 [configuration createNativeConfiguration]);
357 if (!config) {
358 return nil;
359 }
hjonf396f602016-02-11 16:19:06 -0800360 if (self = [super init]) {
361 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800362 _nativeConstraints = constraints.nativeConstraints;
Jonas Oreland285f83d2020-02-07 10:30:08 +0100363 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get());
364
365 webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release());
366 deps.observer = _observer.get();
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000367 auto result = factory.nativeFactory->CreatePeerConnectionOrError(*config, std::move(deps));
Jonas Oreland285f83d2020-02-07 10:30:08 +0100368
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000369 if (!result.ok()) {
skvlad588783a2016-08-11 14:29:25 -0700370 return nil;
371 }
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000372 _peerConnection = result.MoveValue();
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300373 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800374 _localStreams = [[NSMutableArray alloc] init];
375 _delegate = delegate;
376 }
377 return self;
378}
379
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200380- (NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800381 return [_localStreams copy];
382}
383
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200384- (RTC_OBJC_TYPE(RTCSessionDescription) *)localDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700385 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
386 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
387 RTC_FROM_HERE, [self] {
388 const webrtc::SessionDescriptionInterface *description =
389 _peerConnection->local_description();
390 return description ?
391 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
392 nil;
393 });
hjonf396f602016-02-11 16:19:06 -0800394}
395
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200396- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700397 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
398 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
399 RTC_FROM_HERE, [self] {
400 const webrtc::SessionDescriptionInterface *description =
401 _peerConnection->remote_description();
402 return description ?
403 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
404 nil;
405 });
hjonf396f602016-02-11 16:19:06 -0800406}
407
408- (RTCSignalingState)signalingState {
409 return [[self class]
410 signalingStateForNativeState:_peerConnection->signaling_state()];
411}
412
413- (RTCIceConnectionState)iceConnectionState {
414 return [[self class] iceConnectionStateForNativeState:
415 _peerConnection->ice_connection_state()];
416}
417
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100418- (RTCPeerConnectionState)connectionState {
419 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
420}
421
hjonf396f602016-02-11 16:19:06 -0800422- (RTCIceGatheringState)iceGatheringState {
423 return [[self class] iceGatheringStateForNativeState:
424 _peerConnection->ice_gathering_state()];
425}
426
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200427- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200428 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700429 [configuration createNativeConfiguration]);
430 if (!config) {
431 return NO;
432 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800433 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
434 config.get());
Niels Möller2579f0c2019-08-19 09:58:17 +0200435 return _peerConnection->SetConfiguration(*config).ok();
tkchinaac3eb22016-03-09 21:49:40 -0800436}
437
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200438- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
jtteh4eeb5372017-04-03 15:06:37 -0700439 webrtc::PeerConnectionInterface::RTCConfiguration config =
440 _peerConnection->GetConfiguration();
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200441 return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700442}
443
hjonf396f602016-02-11 16:19:06 -0800444- (void)close {
445 _peerConnection->Close();
446}
447
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200448- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700449 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800450 candidate.nativeCandidate);
451 _peerConnection->AddIceCandidate(iceCandidate.get());
452}
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300453- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
454 completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
455 RTC_DCHECK(completionHandler != nil);
Byoungchan Lee8c487572021-08-04 20:55:25 +0900456 _peerConnection->AddIceCandidate(
457 candidate.nativeCandidate, [completionHandler](const auto &error) {
458 if (error.ok()) {
459 completionHandler(nil);
460 } else {
461 NSString *str = [NSString stringForStdString:error.message()];
462 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
463 code:static_cast<NSInteger>(error.type())
464 userInfo:@{NSLocalizedDescriptionKey : str}];
465 completionHandler(err);
466 }
467 });
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300468}
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200469- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700470 std::vector<cricket::Candidate> candidates;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200471 for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700472 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
473 iceCandidate.nativeCandidate);
474 if (candidate) {
475 candidates.push_back(candidate->candidate());
476 // Need to fill the transport name from the sdp_mid.
477 candidates.back().set_transport_name(candidate->sdp_mid());
478 }
479 }
480 if (!candidates.empty()) {
481 _peerConnection->RemoveIceCandidates(candidates);
482 }
483}
484
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200485- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
hjona2f77982016-03-04 07:09:09 -0800486 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800487 RTCLogError(@"Failed to add stream: %@", stream);
488 return;
489 }
490 [_localStreams addObject:stream];
491}
492
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200493- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
hjonf396f602016-02-11 16:19:06 -0800494 _peerConnection->RemoveStream(stream.nativeMediaStream);
495 [_localStreams removeObject:stream];
496}
497
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300498- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
499 streamIds:(NSArray<NSString *> *)streamIds {
Seth Hampson513449e2018-03-06 09:35:56 -0800500 std::vector<std::string> nativeStreamIds;
501 for (NSString *streamId in streamIds) {
502 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800503 }
504 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800505 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800506 if (!nativeSenderOrError.ok()) {
507 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
508 return nil;
509 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200510 return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
511 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800512}
513
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200514- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender {
Steve Anton8cb344a2018-02-27 15:34:53 -0800515 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
516 if (!result) {
517 RTCLogError(@"Failed to remote track %@", sender);
518 }
519 return result;
520}
521
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300522- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200523 (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track {
524 return [self addTransceiverWithTrack:track
525 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800526}
527
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300528- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200529 addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
530 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800531 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
532 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
533 if (!nativeTransceiverOrError.ok()) {
534 RTCLogError(
535 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
536 return nil;
537 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200538 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
539 initWithFactory:self.factory
540 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800541}
542
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300543- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200544 return [self addTransceiverOfType:mediaType
545 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800546}
547
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300548- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
549 addTransceiverOfType:(RTCRtpMediaType)mediaType
550 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800551 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200552 _peerConnection->AddTransceiver(
553 [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit);
Steve Anton8cb344a2018-02-27 15:34:53 -0800554 if (!nativeTransceiverOrError.ok()) {
555 RTCLogError(@"Failed to add transceiver %@: %s",
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200556 [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType],
Steve Anton8cb344a2018-02-27 15:34:53 -0800557 nativeTransceiverOrError.error().message());
558 return nil;
559 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200560 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
561 initWithFactory:self.factory
562 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800563}
564
Yura Yaroshevich92d12702021-03-06 23:55:17 +0300565- (void)restartIce {
566 _peerConnection->RestartIce();
567}
568
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200569- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300570 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
571 RTC_DCHECK(completionHandler != nil);
hjonf396f602016-02-11 16:19:06 -0800572 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
573 observer(new rtc::RefCountedObject
574 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200575 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
576 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
577
578 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800579}
580
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200581- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300582 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
583 RTC_DCHECK(completionHandler != nil);
hjonf396f602016-02-11 16:19:06 -0800584 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
585 observer(new rtc::RefCountedObject
586 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200587 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
588 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
589
590 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800591}
592
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200593- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300594 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
595 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300596 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer(
597 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
Byoungchan Lee33728152021-08-04 20:54:45 +0900598 _peerConnection->SetLocalDescription(sdp.nativeDescription, observer);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300599}
600
601- (void)setLocalDescriptionWithCompletionHandler:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300602 (RTCSetSessionDescriptionCompletionHandler)completionHandler {
603 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300604 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer(
605 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
606 _peerConnection->SetLocalDescription(observer);
hjonf396f602016-02-11 16:19:06 -0800607}
608
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200609- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300610 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
611 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300612 rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer(
613 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
Byoungchan Lee33728152021-08-04 20:54:45 +0900614 _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer);
hjonf396f602016-02-11 16:19:06 -0800615}
616
zstein8b476172017-09-05 14:43:03 -0700617- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
618 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
619 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200620 webrtc::BitrateSettings params;
zstein03adb7c2017-08-09 14:29:42 -0700621 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200622 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700623 }
624 if (currentBitrateBps != nil) {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200625 params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700626 }
627 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200628 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700629 }
630 return _peerConnection->SetBitrate(params).ok();
631}
632
ivoc14d5dbe2016-07-04 07:06:55 -0700633- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
634 maxSizeInBytes:(int64_t)maxSizeInBytes {
635 RTC_DCHECK(filePath.length);
636 RTC_DCHECK_GT(maxSizeInBytes, 0);
637 RTC_DCHECK(!_hasStartedRtcEventLog);
638 if (_hasStartedRtcEventLog) {
639 RTCLogError(@"Event logging already started.");
640 return NO;
641 }
Niels Möllerdec9f742019-06-03 15:25:20 +0200642 FILE *f = fopen(filePath.UTF8String, "wb");
643 if (!f) {
ivoc14d5dbe2016-07-04 07:06:55 -0700644 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
645 return NO;
646 }
Niels Möller695cf6a2019-05-13 12:27:23 +0200647 // TODO(eladalon): It would be better to not allow negative values into PC.
648 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
649 rtc::saturated_cast<size_t>(maxSizeInBytes);
650
651 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200652 std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
ivoc14d5dbe2016-07-04 07:06:55 -0700653 return _hasStartedRtcEventLog;
654}
655
656- (void)stopRtcEventLog {
657 _peerConnection->StopRtcEventLog();
658 _hasStartedRtcEventLog = NO;
659}
660
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200661- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId {
skvladf3569c82016-04-29 15:30:16 -0700662 std::string nativeKind = [NSString stdStringForString:kind];
663 std::string nativeStreamId = [NSString stdStringForString:streamId];
664 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
665 _peerConnection->CreateSender(nativeKind, nativeStreamId));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200666 return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
667 nativeRtpSender:nativeSender] :
668 nil;
skvladf3569c82016-04-29 15:30:16 -0700669}
670
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200671- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders {
skvlad79b4b872016-04-08 17:28:55 -0700672 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
673 _peerConnection->GetSenders());
674 NSMutableArray *senders = [[NSMutableArray alloc] init];
675 for (const auto &nativeSender : nativeSenders) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200676 RTC_OBJC_TYPE(RTCRtpSender) *sender =
677 [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
678 nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700679 [senders addObject:sender];
680 }
681 return senders;
682}
683
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200684- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700685 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
686 _peerConnection->GetReceivers());
687 NSMutableArray *receivers = [[NSMutableArray alloc] init];
688 for (const auto &nativeReceiver : nativeReceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200689 RTC_OBJC_TYPE(RTCRtpReceiver) *receiver =
690 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory
691 nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700692 [receivers addObject:receiver];
693 }
694 return receivers;
695}
696
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200697- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers {
Steve Anton8cb344a2018-02-27 15:34:53 -0800698 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
699 _peerConnection->GetTransceivers());
700 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
Mirko Bonadei739baf02019-01-27 17:29:42 +0100701 for (const auto &nativeTransceiver : nativeTransceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200702 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
703 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory
704 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800705 [transceivers addObject:transceiver];
706 }
707 return transceivers;
708}
709
hjonf396f602016-02-11 16:19:06 -0800710#pragma mark - Private
711
712+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
713 (RTCSignalingState)state {
714 switch (state) {
715 case RTCSignalingStateStable:
716 return webrtc::PeerConnectionInterface::kStable;
717 case RTCSignalingStateHaveLocalOffer:
718 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
719 case RTCSignalingStateHaveLocalPrAnswer:
720 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
721 case RTCSignalingStateHaveRemoteOffer:
722 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
723 case RTCSignalingStateHaveRemotePrAnswer:
724 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
725 case RTCSignalingStateClosed:
726 return webrtc::PeerConnectionInterface::kClosed;
727 }
728}
729
730+ (RTCSignalingState)signalingStateForNativeState:
731 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
732 switch (nativeState) {
733 case webrtc::PeerConnectionInterface::kStable:
734 return RTCSignalingStateStable;
735 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
736 return RTCSignalingStateHaveLocalOffer;
737 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
738 return RTCSignalingStateHaveLocalPrAnswer;
739 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
740 return RTCSignalingStateHaveRemoteOffer;
741 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
742 return RTCSignalingStateHaveRemotePrAnswer;
743 case webrtc::PeerConnectionInterface::kClosed:
744 return RTCSignalingStateClosed;
745 }
746}
747
748+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
749 switch (state) {
750 case RTCSignalingStateStable:
751 return @"STABLE";
752 case RTCSignalingStateHaveLocalOffer:
753 return @"HAVE_LOCAL_OFFER";
754 case RTCSignalingStateHaveLocalPrAnswer:
755 return @"HAVE_LOCAL_PRANSWER";
756 case RTCSignalingStateHaveRemoteOffer:
757 return @"HAVE_REMOTE_OFFER";
758 case RTCSignalingStateHaveRemotePrAnswer:
759 return @"HAVE_REMOTE_PRANSWER";
760 case RTCSignalingStateClosed:
761 return @"CLOSED";
762 }
763}
764
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100765+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
766 (RTCPeerConnectionState)state {
767 switch (state) {
768 case RTCPeerConnectionStateNew:
769 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
770 case RTCPeerConnectionStateConnecting:
771 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
772 case RTCPeerConnectionStateConnected:
773 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
774 case RTCPeerConnectionStateFailed:
775 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
776 case RTCPeerConnectionStateDisconnected:
777 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
778 case RTCPeerConnectionStateClosed:
779 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
780 }
781}
782
783+ (RTCPeerConnectionState)connectionStateForNativeState:
784 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
785 switch (nativeState) {
786 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
787 return RTCPeerConnectionStateNew;
788 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
789 return RTCPeerConnectionStateConnecting;
790 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
791 return RTCPeerConnectionStateConnected;
792 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
793 return RTCPeerConnectionStateFailed;
794 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
795 return RTCPeerConnectionStateDisconnected;
796 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
797 return RTCPeerConnectionStateClosed;
798 }
799}
800
801+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
802 switch (state) {
803 case RTCPeerConnectionStateNew:
804 return @"NEW";
805 case RTCPeerConnectionStateConnecting:
806 return @"CONNECTING";
807 case RTCPeerConnectionStateConnected:
808 return @"CONNECTED";
809 case RTCPeerConnectionStateFailed:
810 return @"FAILED";
811 case RTCPeerConnectionStateDisconnected:
812 return @"DISCONNECTED";
813 case RTCPeerConnectionStateClosed:
814 return @"CLOSED";
815 }
816}
817
hjonf396f602016-02-11 16:19:06 -0800818+ (webrtc::PeerConnectionInterface::IceConnectionState)
819 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
820 switch (state) {
821 case RTCIceConnectionStateNew:
822 return webrtc::PeerConnectionInterface::kIceConnectionNew;
823 case RTCIceConnectionStateChecking:
824 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
825 case RTCIceConnectionStateConnected:
826 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
827 case RTCIceConnectionStateCompleted:
828 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
829 case RTCIceConnectionStateFailed:
830 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
831 case RTCIceConnectionStateDisconnected:
832 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
833 case RTCIceConnectionStateClosed:
834 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700835 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800836 return webrtc::PeerConnectionInterface::kIceConnectionMax;
837 }
838}
839
840+ (RTCIceConnectionState)iceConnectionStateForNativeState:
841 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
842 switch (nativeState) {
843 case webrtc::PeerConnectionInterface::kIceConnectionNew:
844 return RTCIceConnectionStateNew;
845 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
846 return RTCIceConnectionStateChecking;
847 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
848 return RTCIceConnectionStateConnected;
849 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
850 return RTCIceConnectionStateCompleted;
851 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
852 return RTCIceConnectionStateFailed;
853 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
854 return RTCIceConnectionStateDisconnected;
855 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
856 return RTCIceConnectionStateClosed;
857 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700858 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800859 }
860}
861
862+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
863 switch (state) {
864 case RTCIceConnectionStateNew:
865 return @"NEW";
866 case RTCIceConnectionStateChecking:
867 return @"CHECKING";
868 case RTCIceConnectionStateConnected:
869 return @"CONNECTED";
870 case RTCIceConnectionStateCompleted:
871 return @"COMPLETED";
872 case RTCIceConnectionStateFailed:
873 return @"FAILED";
874 case RTCIceConnectionStateDisconnected:
875 return @"DISCONNECTED";
876 case RTCIceConnectionStateClosed:
877 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700878 case RTCIceConnectionStateCount:
879 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800880 }
881}
882
883+ (webrtc::PeerConnectionInterface::IceGatheringState)
884 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
885 switch (state) {
886 case RTCIceGatheringStateNew:
887 return webrtc::PeerConnectionInterface::kIceGatheringNew;
888 case RTCIceGatheringStateGathering:
889 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
890 case RTCIceGatheringStateComplete:
891 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
892 }
893}
894
895+ (RTCIceGatheringState)iceGatheringStateForNativeState:
896 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
897 switch (nativeState) {
898 case webrtc::PeerConnectionInterface::kIceGatheringNew:
899 return RTCIceGatheringStateNew;
900 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
901 return RTCIceGatheringStateGathering;
902 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
903 return RTCIceGatheringStateComplete;
904 }
905}
906
907+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
908 switch (state) {
909 case RTCIceGatheringStateNew:
910 return @"NEW";
911 case RTCIceGatheringStateGathering:
912 return @"GATHERING";
913 case RTCIceGatheringStateComplete:
914 return @"COMPLETE";
915 }
916}
917
918+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
919 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
920 switch (level) {
921 case RTCStatsOutputLevelStandard:
922 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
923 case RTCStatsOutputLevelDebug:
924 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
925 }
926}
927
hjonf396f602016-02-11 16:19:06 -0800928- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
929 return _peerConnection;
930}
931
932@end