blob: 04b07f75336a36b81a29b368874a341946af9a3b [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"
hbosbd3dda62016-09-09 01:36:28 -070016#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070017#import "RTCMediaConstraints+Private.h"
18#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080019#import "RTCMediaStreamTrack+Private.h"
Magnus Jedvert0af86d12017-10-28 16:26:55 +020020#import "RTCPeerConnection+Native.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"
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070032#include "api/media_transport_interface.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020033#include "api/rtc_event_log_output_file.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/checks.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020035#include "rtc_base/numerics/safe_conversions.h"
hjonf396f602016-02-11 16:19:06 -080036
hjonf396f602016-02-11 16:19:06 -080037NSString * const kRTCPeerConnectionErrorDomain =
38 @"org.webrtc.RTCPeerConnection";
39int const kRTCPeerConnnectionSessionDescriptionError = -1;
40
41namespace webrtc {
42
43class CreateSessionDescriptionObserverAdapter
44 : public CreateSessionDescriptionObserver {
45 public:
46 CreateSessionDescriptionObserverAdapter(
47 void (^completionHandler)(RTCSessionDescription *sessionDescription,
48 NSError *error)) {
49 completion_handler_ = completionHandler;
50 }
51
Mirko Bonadei17aff352018-07-26 12:20:40 +020052 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080053
54 void OnSuccess(SessionDescriptionInterface *desc) override {
55 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070056 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
57 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080058 RTCSessionDescription* session =
59 [[RTCSessionDescription alloc] initWithNativeDescription:
60 description.get()];
61 completion_handler_(session, nil);
62 completion_handler_ = nil;
63 }
64
Harald Alvestrand73771a82018-05-24 10:53:49 +020065 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080066 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020067 // TODO(hta): Add handling of error.type()
68 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080069 NSError* err =
70 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
71 code:kRTCPeerConnnectionSessionDescriptionError
72 userInfo:@{ NSLocalizedDescriptionKey : str }];
73 completion_handler_(nil, err);
74 completion_handler_ = nil;
75 }
76
77 private:
78 void (^completion_handler_)
79 (RTCSessionDescription *sessionDescription, NSError *error);
80};
81
82class SetSessionDescriptionObserverAdapter :
83 public SetSessionDescriptionObserver {
84 public:
85 SetSessionDescriptionObserverAdapter(void (^completionHandler)
86 (NSError *error)) {
87 completion_handler_ = completionHandler;
88 }
89
Mirko Bonadei17aff352018-07-26 12:20:40 +020090 ~SetSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080091
92 void OnSuccess() override {
93 RTC_DCHECK(completion_handler_);
94 completion_handler_(nil);
95 completion_handler_ = nil;
96 }
97
Harald Alvestrand73771a82018-05-24 10:53:49 +020098 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080099 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200100 // TODO(hta): Add handling of error.type()
101 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800102 NSError* err =
103 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
104 code:kRTCPeerConnnectionSessionDescriptionError
105 userInfo:@{ NSLocalizedDescriptionKey : str }];
106 completion_handler_(err);
107 completion_handler_ = nil;
108 }
109
110 private:
111 void (^completion_handler_)(NSError *error);
112};
113
114PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
115 RTCPeerConnection *peerConnection) {
116 peer_connection_ = peerConnection;
117}
118
119PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
120 peer_connection_ = nil;
121}
122
123void PeerConnectionDelegateAdapter::OnSignalingChange(
124 PeerConnectionInterface::SignalingState new_state) {
125 RTCSignalingState state =
126 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
127 RTCPeerConnection *peer_connection = peer_connection_;
128 [peer_connection.delegate peerConnection:peer_connection
129 didChangeSignalingState:state];
130}
131
132void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700133 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800134 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300135 RTCMediaStream *mediaStream =
136 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800137 [peer_connection.delegate peerConnection:peer_connection
138 didAddStream:mediaStream];
139}
140
141void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700142 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800143 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300144 RTCMediaStream *mediaStream =
145 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
146
hjonf396f602016-02-11 16:19:06 -0800147 [peer_connection.delegate peerConnection:peer_connection
148 didRemoveStream:mediaStream];
149}
150
Steve Anton8cb344a2018-02-27 15:34:53 -0800151void PeerConnectionDelegateAdapter::OnTrack(
152 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Steve Anton8cb344a2018-02-27 15:34:53 -0800153 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300154 RTCRtpTransceiver *transceiver =
155 [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory
156 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800157 if ([peer_connection.delegate
158 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
159 [peer_connection.delegate peerConnection:peer_connection
160 didStartReceivingOnTransceiver:transceiver];
161 }
162}
163
hjonf396f602016-02-11 16:19:06 -0800164void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700165 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800166 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300167 RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory
168 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800169 [peer_connection.delegate peerConnection:peer_connection
170 didOpenDataChannel:dataChannel];
171}
172
173void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
174 RTCPeerConnection *peer_connection = peer_connection_;
175 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
176}
177
178void PeerConnectionDelegateAdapter::OnIceConnectionChange(
179 PeerConnectionInterface::IceConnectionState new_state) {
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100180 RTCIceConnectionState state = [RTCPeerConnection iceConnectionStateForNativeState:new_state];
181 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
182}
183
Qingsi Wang36e31472019-05-29 11:37:26 -0700184void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
185 PeerConnectionInterface::IceConnectionState new_state) {
186 if ([peer_connection_.delegate
187 respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) {
188 RTCIceConnectionState state = [RTCPeerConnection iceConnectionStateForNativeState:new_state];
189 [peer_connection_.delegate peerConnection:peer_connection_
190 didChangeStandardizedIceConnectionState:state];
191 }
192}
193
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100194void PeerConnectionDelegateAdapter::OnConnectionChange(
195 PeerConnectionInterface::PeerConnectionState new_state) {
196 if ([peer_connection_.delegate
197 respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) {
198 RTCPeerConnectionState state = [RTCPeerConnection connectionStateForNativeState:new_state];
199 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
200 }
hjonf396f602016-02-11 16:19:06 -0800201}
202
203void PeerConnectionDelegateAdapter::OnIceGatheringChange(
204 PeerConnectionInterface::IceGatheringState new_state) {
205 RTCIceGatheringState state =
206 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
207 RTCPeerConnection *peer_connection = peer_connection_;
208 [peer_connection.delegate peerConnection:peer_connection
209 didChangeIceGatheringState:state];
210}
211
212void PeerConnectionDelegateAdapter::OnIceCandidate(
213 const IceCandidateInterface *candidate) {
214 RTCIceCandidate *iceCandidate =
215 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
216 RTCPeerConnection *peer_connection = peer_connection_;
217 [peer_connection.delegate peerConnection:peer_connection
218 didGenerateIceCandidate:iceCandidate];
219}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700220
221void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
222 const std::vector<cricket::Candidate>& candidates) {
223 NSMutableArray* ice_candidates =
224 [NSMutableArray arrayWithCapacity:candidates.size()];
225 for (const auto& candidate : candidates) {
226 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
227 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
228 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
229 initWithNativeCandidate:candidate_wrapper.get()];
230 [ice_candidates addObject:ice_candidate];
231 }
232 RTCPeerConnection* peer_connection = peer_connection_;
233 [peer_connection.delegate peerConnection:peer_connection
234 didRemoveIceCandidates:ice_candidates];
235}
236
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300237void PeerConnectionDelegateAdapter::OnAddTrack(
238 rtc::scoped_refptr<RtpReceiverInterface> receiver,
239 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
240 RTCPeerConnection *peer_connection = peer_connection_;
241 if ([peer_connection.delegate
242 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
243 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
244 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300245 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
246 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300247 [mediaStreams addObject:mediaStream];
248 }
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300249 RTCRtpReceiver *rtpReceiver =
250 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300251
252 [peer_connection.delegate peerConnection:peer_connection
253 didAddReceiver:rtpReceiver
254 streams:mediaStreams];
255 }
256}
257
Zeke Chin8de502b2018-08-21 11:41:07 -0700258void PeerConnectionDelegateAdapter::OnRemoveTrack(
259 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
260 RTCPeerConnection *peer_connection = peer_connection_;
261 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
262 RTCRtpReceiver *rtpReceiver =
263 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
264 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
265 }
266}
267
hjonf396f602016-02-11 16:19:06 -0800268} // namespace webrtc
269
270
271@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300272 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700273 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700274 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800275 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800276 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700277 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800278}
279
280@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300281@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800282
283- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
284 configuration:(RTCConfiguration *)configuration
285 constraints:(RTCMediaConstraints *)constraints
286 delegate:(id<RTCPeerConnectionDelegate>)delegate {
287 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200288 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700289 [configuration createNativeConfiguration]);
290 if (!config) {
291 return nil;
292 }
hjonf396f602016-02-11 16:19:06 -0800293 if (self = [super init]) {
294 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800295 _nativeConstraints = constraints.nativeConstraints;
296 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
297 config.get());
hjonf396f602016-02-11 16:19:06 -0800298 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700299 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700300 nullptr,
301 nullptr,
302 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700303 if (!_peerConnection) {
304 return nil;
305 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300306 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800307 _localStreams = [[NSMutableArray alloc] init];
308 _delegate = delegate;
309 }
310 return self;
311}
312
vopatop.skam96b6b832016-08-18 14:21:20 -0700313- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800314 return [_localStreams copy];
315}
316
317- (RTCSessionDescription *)localDescription {
318 const webrtc::SessionDescriptionInterface *description =
319 _peerConnection->local_description();
320 return description ?
321 [[RTCSessionDescription alloc] initWithNativeDescription:description]
322 : nil;
323}
324
325- (RTCSessionDescription *)remoteDescription {
326 const webrtc::SessionDescriptionInterface *description =
327 _peerConnection->remote_description();
328 return description ?
329 [[RTCSessionDescription alloc] initWithNativeDescription:description]
330 : nil;
331}
332
333- (RTCSignalingState)signalingState {
334 return [[self class]
335 signalingStateForNativeState:_peerConnection->signaling_state()];
336}
337
338- (RTCIceConnectionState)iceConnectionState {
339 return [[self class] iceConnectionStateForNativeState:
340 _peerConnection->ice_connection_state()];
341}
342
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100343- (RTCPeerConnectionState)connectionState {
344 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
345}
346
hjonf396f602016-02-11 16:19:06 -0800347- (RTCIceGatheringState)iceGatheringState {
348 return [[self class] iceGatheringStateForNativeState:
349 _peerConnection->ice_gathering_state()];
350}
351
tkchinaac3eb22016-03-09 21:49:40 -0800352- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200353 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700354 [configuration createNativeConfiguration]);
355 if (!config) {
356 return NO;
357 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800358 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
359 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200360 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800361}
362
jtteh4eeb5372017-04-03 15:06:37 -0700363- (RTCConfiguration *)configuration {
364 webrtc::PeerConnectionInterface::RTCConfiguration config =
365 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700366 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700367}
368
hjonf396f602016-02-11 16:19:06 -0800369- (void)close {
370 _peerConnection->Close();
371}
372
373- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700374 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800375 candidate.nativeCandidate);
376 _peerConnection->AddIceCandidate(iceCandidate.get());
377}
378
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700379- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
380 std::vector<cricket::Candidate> candidates;
381 for (RTCIceCandidate *iceCandidate in iceCandidates) {
382 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
383 iceCandidate.nativeCandidate);
384 if (candidate) {
385 candidates.push_back(candidate->candidate());
386 // Need to fill the transport name from the sdp_mid.
387 candidates.back().set_transport_name(candidate->sdp_mid());
388 }
389 }
390 if (!candidates.empty()) {
391 _peerConnection->RemoveIceCandidates(candidates);
392 }
393}
394
hjonf396f602016-02-11 16:19:06 -0800395- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800396 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800397 RTCLogError(@"Failed to add stream: %@", stream);
398 return;
399 }
400 [_localStreams addObject:stream];
401}
402
403- (void)removeStream:(RTCMediaStream *)stream {
404 _peerConnection->RemoveStream(stream.nativeMediaStream);
405 [_localStreams removeObject:stream];
406}
407
Seth Hampson513449e2018-03-06 09:35:56 -0800408- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
409 std::vector<std::string> nativeStreamIds;
410 for (NSString *streamId in streamIds) {
411 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800412 }
413 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800414 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800415 if (!nativeSenderOrError.ok()) {
416 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
417 return nil;
418 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300419 return [[RTCRtpSender alloc] initWithFactory:self.factory
420 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800421}
422
423- (BOOL)removeTrack:(RTCRtpSender *)sender {
424 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
425 if (!result) {
426 RTCLogError(@"Failed to remote track %@", sender);
427 }
428 return result;
429}
430
431- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
432 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
433}
434
435- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
436 init:(RTCRtpTransceiverInit *)init {
437 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
438 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
439 if (!nativeTransceiverOrError.ok()) {
440 RTCLogError(
441 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
442 return nil;
443 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300444 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
445 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800446}
447
448- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
449 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
450}
451
452- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
453 init:(RTCRtpTransceiverInit *)init {
454 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
455 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
456 init.nativeInit);
457 if (!nativeTransceiverOrError.ok()) {
458 RTCLogError(@"Failed to add transceiver %@: %s",
459 [RTCRtpReceiver stringForMediaType:mediaType],
460 nativeTransceiverOrError.error().message());
461 return nil;
462 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300463 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
464 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800465}
466
hjonf396f602016-02-11 16:19:06 -0800467- (void)offerForConstraints:(RTCMediaConstraints *)constraints
468 completionHandler:
469 (void (^)(RTCSessionDescription *sessionDescription,
470 NSError *error))completionHandler {
471 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
472 observer(new rtc::RefCountedObject
473 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200474 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
475 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
476
477 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800478}
479
480- (void)answerForConstraints:(RTCMediaConstraints *)constraints
481 completionHandler:
482 (void (^)(RTCSessionDescription *sessionDescription,
483 NSError *error))completionHandler {
484 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
485 observer(new rtc::RefCountedObject
486 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200487 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
488 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
489
490 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800491}
492
493- (void)setLocalDescription:(RTCSessionDescription *)sdp
494 completionHandler:(void (^)(NSError *error))completionHandler {
495 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
496 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
497 completionHandler));
498 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
499}
500
501- (void)setRemoteDescription:(RTCSessionDescription *)sdp
502 completionHandler:(void (^)(NSError *error))completionHandler {
503 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
504 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
505 completionHandler));
506 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
507}
508
zstein8b476172017-09-05 14:43:03 -0700509- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
510 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
511 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700512 webrtc::PeerConnectionInterface::BitrateParameters params;
513 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200514 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700515 }
516 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200517 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700518 }
519 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200520 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700521 }
522 return _peerConnection->SetBitrate(params).ok();
523}
524
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200525- (void)setBitrateAllocationStrategy:
526 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
527 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
528}
529
ivoc14d5dbe2016-07-04 07:06:55 -0700530- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
531 maxSizeInBytes:(int64_t)maxSizeInBytes {
532 RTC_DCHECK(filePath.length);
533 RTC_DCHECK_GT(maxSizeInBytes, 0);
534 RTC_DCHECK(!_hasStartedRtcEventLog);
535 if (_hasStartedRtcEventLog) {
536 RTCLogError(@"Event logging already started.");
537 return NO;
538 }
Niels Möllerdec9f742019-06-03 15:25:20 +0200539 FILE *f = fopen(filePath.UTF8String, "wb");
540 if (!f) {
ivoc14d5dbe2016-07-04 07:06:55 -0700541 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
542 return NO;
543 }
Niels Möller695cf6a2019-05-13 12:27:23 +0200544 // TODO(eladalon): It would be better to not allow negative values into PC.
545 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
546 rtc::saturated_cast<size_t>(maxSizeInBytes);
547
548 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
Niels Möllerdec9f742019-06-03 15:25:20 +0200549 absl::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
ivoc14d5dbe2016-07-04 07:06:55 -0700550 return _hasStartedRtcEventLog;
551}
552
553- (void)stopRtcEventLog {
554 _peerConnection->StopRtcEventLog();
555 _hasStartedRtcEventLog = NO;
556}
557
skvladf3569c82016-04-29 15:30:16 -0700558- (RTCRtpSender *)senderWithKind:(NSString *)kind
559 streamId:(NSString *)streamId {
560 std::string nativeKind = [NSString stdStringForString:kind];
561 std::string nativeStreamId = [NSString stdStringForString:streamId];
562 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
563 _peerConnection->CreateSender(nativeKind, nativeStreamId));
564 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300565 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
566 nil;
skvladf3569c82016-04-29 15:30:16 -0700567}
568
skvlad79b4b872016-04-08 17:28:55 -0700569- (NSArray<RTCRtpSender *> *)senders {
570 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
571 _peerConnection->GetSenders());
572 NSMutableArray *senders = [[NSMutableArray alloc] init];
573 for (const auto &nativeSender : nativeSenders) {
574 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300575 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700576 [senders addObject:sender];
577 }
578 return senders;
579}
580
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700581- (NSArray<RTCRtpReceiver *> *)receivers {
582 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
583 _peerConnection->GetReceivers());
584 NSMutableArray *receivers = [[NSMutableArray alloc] init];
585 for (const auto &nativeReceiver : nativeReceivers) {
586 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300587 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700588 [receivers addObject:receiver];
589 }
590 return receivers;
591}
592
Steve Anton8cb344a2018-02-27 15:34:53 -0800593- (NSArray<RTCRtpTransceiver *> *)transceivers {
594 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
595 _peerConnection->GetTransceivers());
596 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
Mirko Bonadei739baf02019-01-27 17:29:42 +0100597 for (const auto &nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300598 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
599 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800600 [transceivers addObject:transceiver];
601 }
602 return transceivers;
603}
604
hjonf396f602016-02-11 16:19:06 -0800605#pragma mark - Private
606
607+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
608 (RTCSignalingState)state {
609 switch (state) {
610 case RTCSignalingStateStable:
611 return webrtc::PeerConnectionInterface::kStable;
612 case RTCSignalingStateHaveLocalOffer:
613 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
614 case RTCSignalingStateHaveLocalPrAnswer:
615 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
616 case RTCSignalingStateHaveRemoteOffer:
617 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
618 case RTCSignalingStateHaveRemotePrAnswer:
619 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
620 case RTCSignalingStateClosed:
621 return webrtc::PeerConnectionInterface::kClosed;
622 }
623}
624
625+ (RTCSignalingState)signalingStateForNativeState:
626 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
627 switch (nativeState) {
628 case webrtc::PeerConnectionInterface::kStable:
629 return RTCSignalingStateStable;
630 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
631 return RTCSignalingStateHaveLocalOffer;
632 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
633 return RTCSignalingStateHaveLocalPrAnswer;
634 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
635 return RTCSignalingStateHaveRemoteOffer;
636 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
637 return RTCSignalingStateHaveRemotePrAnswer;
638 case webrtc::PeerConnectionInterface::kClosed:
639 return RTCSignalingStateClosed;
640 }
641}
642
643+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
644 switch (state) {
645 case RTCSignalingStateStable:
646 return @"STABLE";
647 case RTCSignalingStateHaveLocalOffer:
648 return @"HAVE_LOCAL_OFFER";
649 case RTCSignalingStateHaveLocalPrAnswer:
650 return @"HAVE_LOCAL_PRANSWER";
651 case RTCSignalingStateHaveRemoteOffer:
652 return @"HAVE_REMOTE_OFFER";
653 case RTCSignalingStateHaveRemotePrAnswer:
654 return @"HAVE_REMOTE_PRANSWER";
655 case RTCSignalingStateClosed:
656 return @"CLOSED";
657 }
658}
659
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100660+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
661 (RTCPeerConnectionState)state {
662 switch (state) {
663 case RTCPeerConnectionStateNew:
664 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
665 case RTCPeerConnectionStateConnecting:
666 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
667 case RTCPeerConnectionStateConnected:
668 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
669 case RTCPeerConnectionStateFailed:
670 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
671 case RTCPeerConnectionStateDisconnected:
672 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
673 case RTCPeerConnectionStateClosed:
674 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
675 }
676}
677
678+ (RTCPeerConnectionState)connectionStateForNativeState:
679 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
680 switch (nativeState) {
681 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
682 return RTCPeerConnectionStateNew;
683 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
684 return RTCPeerConnectionStateConnecting;
685 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
686 return RTCPeerConnectionStateConnected;
687 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
688 return RTCPeerConnectionStateFailed;
689 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
690 return RTCPeerConnectionStateDisconnected;
691 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
692 return RTCPeerConnectionStateClosed;
693 }
694}
695
696+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
697 switch (state) {
698 case RTCPeerConnectionStateNew:
699 return @"NEW";
700 case RTCPeerConnectionStateConnecting:
701 return @"CONNECTING";
702 case RTCPeerConnectionStateConnected:
703 return @"CONNECTED";
704 case RTCPeerConnectionStateFailed:
705 return @"FAILED";
706 case RTCPeerConnectionStateDisconnected:
707 return @"DISCONNECTED";
708 case RTCPeerConnectionStateClosed:
709 return @"CLOSED";
710 }
711}
712
hjonf396f602016-02-11 16:19:06 -0800713+ (webrtc::PeerConnectionInterface::IceConnectionState)
714 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
715 switch (state) {
716 case RTCIceConnectionStateNew:
717 return webrtc::PeerConnectionInterface::kIceConnectionNew;
718 case RTCIceConnectionStateChecking:
719 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
720 case RTCIceConnectionStateConnected:
721 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
722 case RTCIceConnectionStateCompleted:
723 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
724 case RTCIceConnectionStateFailed:
725 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
726 case RTCIceConnectionStateDisconnected:
727 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
728 case RTCIceConnectionStateClosed:
729 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700730 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800731 return webrtc::PeerConnectionInterface::kIceConnectionMax;
732 }
733}
734
735+ (RTCIceConnectionState)iceConnectionStateForNativeState:
736 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
737 switch (nativeState) {
738 case webrtc::PeerConnectionInterface::kIceConnectionNew:
739 return RTCIceConnectionStateNew;
740 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
741 return RTCIceConnectionStateChecking;
742 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
743 return RTCIceConnectionStateConnected;
744 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
745 return RTCIceConnectionStateCompleted;
746 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
747 return RTCIceConnectionStateFailed;
748 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
749 return RTCIceConnectionStateDisconnected;
750 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
751 return RTCIceConnectionStateClosed;
752 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700753 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800754 }
755}
756
757+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
758 switch (state) {
759 case RTCIceConnectionStateNew:
760 return @"NEW";
761 case RTCIceConnectionStateChecking:
762 return @"CHECKING";
763 case RTCIceConnectionStateConnected:
764 return @"CONNECTED";
765 case RTCIceConnectionStateCompleted:
766 return @"COMPLETED";
767 case RTCIceConnectionStateFailed:
768 return @"FAILED";
769 case RTCIceConnectionStateDisconnected:
770 return @"DISCONNECTED";
771 case RTCIceConnectionStateClosed:
772 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700773 case RTCIceConnectionStateCount:
774 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800775 }
776}
777
778+ (webrtc::PeerConnectionInterface::IceGatheringState)
779 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
780 switch (state) {
781 case RTCIceGatheringStateNew:
782 return webrtc::PeerConnectionInterface::kIceGatheringNew;
783 case RTCIceGatheringStateGathering:
784 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
785 case RTCIceGatheringStateComplete:
786 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
787 }
788}
789
790+ (RTCIceGatheringState)iceGatheringStateForNativeState:
791 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
792 switch (nativeState) {
793 case webrtc::PeerConnectionInterface::kIceGatheringNew:
794 return RTCIceGatheringStateNew;
795 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
796 return RTCIceGatheringStateGathering;
797 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
798 return RTCIceGatheringStateComplete;
799 }
800}
801
802+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
803 switch (state) {
804 case RTCIceGatheringStateNew:
805 return @"NEW";
806 case RTCIceGatheringStateGathering:
807 return @"GATHERING";
808 case RTCIceGatheringStateComplete:
809 return @"COMPLETE";
810 }
811}
812
813+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
814 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
815 switch (level) {
816 case RTCStatsOutputLevelStandard:
817 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
818 case RTCStatsOutputLevelDebug:
819 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
820 }
821}
822
hjonf396f602016-02-11 16:19:06 -0800823- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
824 return _peerConnection;
825}
826
827@end