blob: 947bba6e1cf04725d117650cbbb38e2219992621 [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
13#import "NSString+StdString.h"
14#import "RTCConfiguration+Private.h"
15#import "RTCDataChannel+Private.h"
16#import "RTCIceCandidate+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"
Magnus Jedvert0af86d12017-10-28 16:26:55 +020021#import "RTCPeerConnection+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070022#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070023#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070024#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080025#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070026#import "RTCSessionDescription+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070027#import "WebRTC/RTCLogging.h"
hjonf396f602016-02-11 16:19:06 -080028
kwibergbfefb032016-05-01 14:53:46 -070029#include <memory>
30
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "api/jsepicecandidate.h"
32#include "rtc_base/checks.h"
hjonf396f602016-02-11 16:19:06 -080033
hjonf396f602016-02-11 16:19:06 -080034NSString * const kRTCPeerConnectionErrorDomain =
35 @"org.webrtc.RTCPeerConnection";
36int const kRTCPeerConnnectionSessionDescriptionError = -1;
37
38namespace webrtc {
39
40class CreateSessionDescriptionObserverAdapter
41 : public CreateSessionDescriptionObserver {
42 public:
43 CreateSessionDescriptionObserverAdapter(
44 void (^completionHandler)(RTCSessionDescription *sessionDescription,
45 NSError *error)) {
46 completion_handler_ = completionHandler;
47 }
48
49 ~CreateSessionDescriptionObserverAdapter() {
50 completion_handler_ = nil;
51 }
52
53 void OnSuccess(SessionDescriptionInterface *desc) override {
54 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070055 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
56 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080057 RTCSessionDescription* session =
58 [[RTCSessionDescription alloc] initWithNativeDescription:
59 description.get()];
60 completion_handler_(session, nil);
61 completion_handler_ = nil;
62 }
63
Harald Alvestrand73771a82018-05-24 10:53:49 +020064 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080065 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020066 // TODO(hta): Add handling of error.type()
67 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080068 NSError* err =
69 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
70 code:kRTCPeerConnnectionSessionDescriptionError
71 userInfo:@{ NSLocalizedDescriptionKey : str }];
72 completion_handler_(nil, err);
73 completion_handler_ = nil;
74 }
75
76 private:
77 void (^completion_handler_)
78 (RTCSessionDescription *sessionDescription, NSError *error);
79};
80
81class SetSessionDescriptionObserverAdapter :
82 public SetSessionDescriptionObserver {
83 public:
84 SetSessionDescriptionObserverAdapter(void (^completionHandler)
85 (NSError *error)) {
86 completion_handler_ = completionHandler;
87 }
88
89 ~SetSessionDescriptionObserverAdapter() {
90 completion_handler_ = nil;
91 }
92
93 void OnSuccess() override {
94 RTC_DCHECK(completion_handler_);
95 completion_handler_(nil);
96 completion_handler_ = nil;
97 }
98
Harald Alvestrand73771a82018-05-24 10:53:49 +020099 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -0800100 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200101 // TODO(hta): Add handling of error.type()
102 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800103 NSError* err =
104 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
105 code:kRTCPeerConnnectionSessionDescriptionError
106 userInfo:@{ NSLocalizedDescriptionKey : str }];
107 completion_handler_(err);
108 completion_handler_ = nil;
109 }
110
111 private:
112 void (^completion_handler_)(NSError *error);
113};
114
115PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
116 RTCPeerConnection *peerConnection) {
117 peer_connection_ = peerConnection;
118}
119
120PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
121 peer_connection_ = nil;
122}
123
124void PeerConnectionDelegateAdapter::OnSignalingChange(
125 PeerConnectionInterface::SignalingState new_state) {
126 RTCSignalingState state =
127 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
128 RTCPeerConnection *peer_connection = peer_connection_;
129 [peer_connection.delegate peerConnection:peer_connection
130 didChangeSignalingState:state];
131}
132
133void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700134 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800135 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300136 RTCMediaStream *mediaStream =
137 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800138 [peer_connection.delegate peerConnection:peer_connection
139 didAddStream:mediaStream];
140}
141
142void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700143 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800144 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300145 RTCMediaStream *mediaStream =
146 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
147
hjonf396f602016-02-11 16:19:06 -0800148 [peer_connection.delegate peerConnection:peer_connection
149 didRemoveStream:mediaStream];
150}
151
Steve Anton8cb344a2018-02-27 15:34:53 -0800152void PeerConnectionDelegateAdapter::OnTrack(
153 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Steve Anton8cb344a2018-02-27 15:34:53 -0800154 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300155 RTCRtpTransceiver *transceiver =
156 [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory
157 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800158 if ([peer_connection.delegate
159 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
160 [peer_connection.delegate peerConnection:peer_connection
161 didStartReceivingOnTransceiver:transceiver];
162 }
163}
164
hjonf396f602016-02-11 16:19:06 -0800165void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700166 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800167 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300168 RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory
169 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800170 [peer_connection.delegate peerConnection:peer_connection
171 didOpenDataChannel:dataChannel];
172}
173
174void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
175 RTCPeerConnection *peer_connection = peer_connection_;
176 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
177}
178
179void PeerConnectionDelegateAdapter::OnIceConnectionChange(
180 PeerConnectionInterface::IceConnectionState new_state) {
181 RTCIceConnectionState state =
182 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
183 RTCPeerConnection *peer_connection = peer_connection_;
184 [peer_connection.delegate peerConnection:peer_connection
185 didChangeIceConnectionState:state];
186}
187
188void PeerConnectionDelegateAdapter::OnIceGatheringChange(
189 PeerConnectionInterface::IceGatheringState new_state) {
190 RTCIceGatheringState state =
191 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
192 RTCPeerConnection *peer_connection = peer_connection_;
193 [peer_connection.delegate peerConnection:peer_connection
194 didChangeIceGatheringState:state];
195}
196
197void PeerConnectionDelegateAdapter::OnIceCandidate(
198 const IceCandidateInterface *candidate) {
199 RTCIceCandidate *iceCandidate =
200 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
201 RTCPeerConnection *peer_connection = peer_connection_;
202 [peer_connection.delegate peerConnection:peer_connection
203 didGenerateIceCandidate:iceCandidate];
204}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700205
206void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
207 const std::vector<cricket::Candidate>& candidates) {
208 NSMutableArray* ice_candidates =
209 [NSMutableArray arrayWithCapacity:candidates.size()];
210 for (const auto& candidate : candidates) {
211 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
212 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
213 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
214 initWithNativeCandidate:candidate_wrapper.get()];
215 [ice_candidates addObject:ice_candidate];
216 }
217 RTCPeerConnection* peer_connection = peer_connection_;
218 [peer_connection.delegate peerConnection:peer_connection
219 didRemoveIceCandidates:ice_candidates];
220}
221
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300222void PeerConnectionDelegateAdapter::OnAddTrack(
223 rtc::scoped_refptr<RtpReceiverInterface> receiver,
224 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
225 RTCPeerConnection *peer_connection = peer_connection_;
226 if ([peer_connection.delegate
227 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
228 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
229 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300230 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
231 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300232 [mediaStreams addObject:mediaStream];
233 }
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300234 RTCRtpReceiver *rtpReceiver =
235 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300236
237 [peer_connection.delegate peerConnection:peer_connection
238 didAddReceiver:rtpReceiver
239 streams:mediaStreams];
240 }
241}
242
hjonf396f602016-02-11 16:19:06 -0800243} // namespace webrtc
244
245
246@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300247 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700248 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700249 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800250 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800251 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700252 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800253}
254
255@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300256@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800257
258- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
259 configuration:(RTCConfiguration *)configuration
260 constraints:(RTCMediaConstraints *)constraints
261 delegate:(id<RTCPeerConnectionDelegate>)delegate {
262 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200263 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700264 [configuration createNativeConfiguration]);
265 if (!config) {
266 return nil;
267 }
hjonf396f602016-02-11 16:19:06 -0800268 if (self = [super init]) {
269 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800270 _nativeConstraints = constraints.nativeConstraints;
271 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
272 config.get());
hjonf396f602016-02-11 16:19:06 -0800273 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700274 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700275 nullptr,
276 nullptr,
277 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700278 if (!_peerConnection) {
279 return nil;
280 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300281 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800282 _localStreams = [[NSMutableArray alloc] init];
283 _delegate = delegate;
284 }
285 return self;
286}
287
vopatop.skam96b6b832016-08-18 14:21:20 -0700288- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800289 return [_localStreams copy];
290}
291
292- (RTCSessionDescription *)localDescription {
293 const webrtc::SessionDescriptionInterface *description =
294 _peerConnection->local_description();
295 return description ?
296 [[RTCSessionDescription alloc] initWithNativeDescription:description]
297 : nil;
298}
299
300- (RTCSessionDescription *)remoteDescription {
301 const webrtc::SessionDescriptionInterface *description =
302 _peerConnection->remote_description();
303 return description ?
304 [[RTCSessionDescription alloc] initWithNativeDescription:description]
305 : nil;
306}
307
308- (RTCSignalingState)signalingState {
309 return [[self class]
310 signalingStateForNativeState:_peerConnection->signaling_state()];
311}
312
313- (RTCIceConnectionState)iceConnectionState {
314 return [[self class] iceConnectionStateForNativeState:
315 _peerConnection->ice_connection_state()];
316}
317
318- (RTCIceGatheringState)iceGatheringState {
319 return [[self class] iceGatheringStateForNativeState:
320 _peerConnection->ice_gathering_state()];
321}
322
tkchinaac3eb22016-03-09 21:49:40 -0800323- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200324 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700325 [configuration createNativeConfiguration]);
326 if (!config) {
327 return NO;
328 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800329 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
330 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200331 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800332}
333
jtteh4eeb5372017-04-03 15:06:37 -0700334- (RTCConfiguration *)configuration {
335 webrtc::PeerConnectionInterface::RTCConfiguration config =
336 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700337 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700338}
339
hjonf396f602016-02-11 16:19:06 -0800340- (void)close {
341 _peerConnection->Close();
342}
343
344- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700345 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800346 candidate.nativeCandidate);
347 _peerConnection->AddIceCandidate(iceCandidate.get());
348}
349
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700350- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
351 std::vector<cricket::Candidate> candidates;
352 for (RTCIceCandidate *iceCandidate in iceCandidates) {
353 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
354 iceCandidate.nativeCandidate);
355 if (candidate) {
356 candidates.push_back(candidate->candidate());
357 // Need to fill the transport name from the sdp_mid.
358 candidates.back().set_transport_name(candidate->sdp_mid());
359 }
360 }
361 if (!candidates.empty()) {
362 _peerConnection->RemoveIceCandidates(candidates);
363 }
364}
365
hjonf396f602016-02-11 16:19:06 -0800366- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800367 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800368 RTCLogError(@"Failed to add stream: %@", stream);
369 return;
370 }
371 [_localStreams addObject:stream];
372}
373
374- (void)removeStream:(RTCMediaStream *)stream {
375 _peerConnection->RemoveStream(stream.nativeMediaStream);
376 [_localStreams removeObject:stream];
377}
378
Seth Hampson513449e2018-03-06 09:35:56 -0800379- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
380 std::vector<std::string> nativeStreamIds;
381 for (NSString *streamId in streamIds) {
382 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800383 }
384 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800385 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800386 if (!nativeSenderOrError.ok()) {
387 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
388 return nil;
389 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300390 return [[RTCRtpSender alloc] initWithFactory:self.factory
391 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800392}
393
394- (BOOL)removeTrack:(RTCRtpSender *)sender {
395 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
396 if (!result) {
397 RTCLogError(@"Failed to remote track %@", sender);
398 }
399 return result;
400}
401
402- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
403 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
404}
405
406- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
407 init:(RTCRtpTransceiverInit *)init {
408 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
409 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
410 if (!nativeTransceiverOrError.ok()) {
411 RTCLogError(
412 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
413 return nil;
414 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300415 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
416 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800417}
418
419- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
420 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
421}
422
423- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
424 init:(RTCRtpTransceiverInit *)init {
425 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
426 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
427 init.nativeInit);
428 if (!nativeTransceiverOrError.ok()) {
429 RTCLogError(@"Failed to add transceiver %@: %s",
430 [RTCRtpReceiver stringForMediaType:mediaType],
431 nativeTransceiverOrError.error().message());
432 return nil;
433 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300434 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
435 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800436}
437
hjonf396f602016-02-11 16:19:06 -0800438- (void)offerForConstraints:(RTCMediaConstraints *)constraints
439 completionHandler:
440 (void (^)(RTCSessionDescription *sessionDescription,
441 NSError *error))completionHandler {
442 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
443 observer(new rtc::RefCountedObject
444 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
445 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
446}
447
448- (void)answerForConstraints:(RTCMediaConstraints *)constraints
449 completionHandler:
450 (void (^)(RTCSessionDescription *sessionDescription,
451 NSError *error))completionHandler {
452 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
453 observer(new rtc::RefCountedObject
454 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
455 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
456}
457
458- (void)setLocalDescription:(RTCSessionDescription *)sdp
459 completionHandler:(void (^)(NSError *error))completionHandler {
460 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
461 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
462 completionHandler));
463 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
464}
465
466- (void)setRemoteDescription:(RTCSessionDescription *)sdp
467 completionHandler:(void (^)(NSError *error))completionHandler {
468 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
469 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
470 completionHandler));
471 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
472}
473
zstein8b476172017-09-05 14:43:03 -0700474- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
475 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
476 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700477 webrtc::PeerConnectionInterface::BitrateParameters params;
478 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200479 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700480 }
481 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200482 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700483 }
484 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200485 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700486 }
487 return _peerConnection->SetBitrate(params).ok();
488}
489
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200490- (void)setBitrateAllocationStrategy:
491 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
492 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
493}
494
ivoc14d5dbe2016-07-04 07:06:55 -0700495- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
496 maxSizeInBytes:(int64_t)maxSizeInBytes {
497 RTC_DCHECK(filePath.length);
498 RTC_DCHECK_GT(maxSizeInBytes, 0);
499 RTC_DCHECK(!_hasStartedRtcEventLog);
500 if (_hasStartedRtcEventLog) {
501 RTCLogError(@"Event logging already started.");
502 return NO;
503 }
504 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
505 S_IRUSR | S_IWUSR);
506 if (fd < 0) {
507 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
508 return NO;
509 }
510 _hasStartedRtcEventLog =
511 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
512 return _hasStartedRtcEventLog;
513}
514
515- (void)stopRtcEventLog {
516 _peerConnection->StopRtcEventLog();
517 _hasStartedRtcEventLog = NO;
518}
519
skvladf3569c82016-04-29 15:30:16 -0700520- (RTCRtpSender *)senderWithKind:(NSString *)kind
521 streamId:(NSString *)streamId {
522 std::string nativeKind = [NSString stdStringForString:kind];
523 std::string nativeStreamId = [NSString stdStringForString:streamId];
524 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
525 _peerConnection->CreateSender(nativeKind, nativeStreamId));
526 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300527 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
528 nil;
skvladf3569c82016-04-29 15:30:16 -0700529}
530
skvlad79b4b872016-04-08 17:28:55 -0700531- (NSArray<RTCRtpSender *> *)senders {
532 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
533 _peerConnection->GetSenders());
534 NSMutableArray *senders = [[NSMutableArray alloc] init];
535 for (const auto &nativeSender : nativeSenders) {
536 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300537 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700538 [senders addObject:sender];
539 }
540 return senders;
541}
542
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700543- (NSArray<RTCRtpReceiver *> *)receivers {
544 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
545 _peerConnection->GetReceivers());
546 NSMutableArray *receivers = [[NSMutableArray alloc] init];
547 for (const auto &nativeReceiver : nativeReceivers) {
548 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300549 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700550 [receivers addObject:receiver];
551 }
552 return receivers;
553}
554
Steve Anton8cb344a2018-02-27 15:34:53 -0800555- (NSArray<RTCRtpTransceiver *> *)transceivers {
556 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
557 _peerConnection->GetTransceivers());
558 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
559 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300560 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
561 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800562 [transceivers addObject:transceiver];
563 }
564 return transceivers;
565}
566
hjonf396f602016-02-11 16:19:06 -0800567#pragma mark - Private
568
569+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
570 (RTCSignalingState)state {
571 switch (state) {
572 case RTCSignalingStateStable:
573 return webrtc::PeerConnectionInterface::kStable;
574 case RTCSignalingStateHaveLocalOffer:
575 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
576 case RTCSignalingStateHaveLocalPrAnswer:
577 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
578 case RTCSignalingStateHaveRemoteOffer:
579 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
580 case RTCSignalingStateHaveRemotePrAnswer:
581 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
582 case RTCSignalingStateClosed:
583 return webrtc::PeerConnectionInterface::kClosed;
584 }
585}
586
587+ (RTCSignalingState)signalingStateForNativeState:
588 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
589 switch (nativeState) {
590 case webrtc::PeerConnectionInterface::kStable:
591 return RTCSignalingStateStable;
592 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
593 return RTCSignalingStateHaveLocalOffer;
594 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
595 return RTCSignalingStateHaveLocalPrAnswer;
596 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
597 return RTCSignalingStateHaveRemoteOffer;
598 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
599 return RTCSignalingStateHaveRemotePrAnswer;
600 case webrtc::PeerConnectionInterface::kClosed:
601 return RTCSignalingStateClosed;
602 }
603}
604
605+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
606 switch (state) {
607 case RTCSignalingStateStable:
608 return @"STABLE";
609 case RTCSignalingStateHaveLocalOffer:
610 return @"HAVE_LOCAL_OFFER";
611 case RTCSignalingStateHaveLocalPrAnswer:
612 return @"HAVE_LOCAL_PRANSWER";
613 case RTCSignalingStateHaveRemoteOffer:
614 return @"HAVE_REMOTE_OFFER";
615 case RTCSignalingStateHaveRemotePrAnswer:
616 return @"HAVE_REMOTE_PRANSWER";
617 case RTCSignalingStateClosed:
618 return @"CLOSED";
619 }
620}
621
622+ (webrtc::PeerConnectionInterface::IceConnectionState)
623 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
624 switch (state) {
625 case RTCIceConnectionStateNew:
626 return webrtc::PeerConnectionInterface::kIceConnectionNew;
627 case RTCIceConnectionStateChecking:
628 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
629 case RTCIceConnectionStateConnected:
630 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
631 case RTCIceConnectionStateCompleted:
632 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
633 case RTCIceConnectionStateFailed:
634 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
635 case RTCIceConnectionStateDisconnected:
636 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
637 case RTCIceConnectionStateClosed:
638 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700639 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800640 return webrtc::PeerConnectionInterface::kIceConnectionMax;
641 }
642}
643
644+ (RTCIceConnectionState)iceConnectionStateForNativeState:
645 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
646 switch (nativeState) {
647 case webrtc::PeerConnectionInterface::kIceConnectionNew:
648 return RTCIceConnectionStateNew;
649 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
650 return RTCIceConnectionStateChecking;
651 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
652 return RTCIceConnectionStateConnected;
653 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
654 return RTCIceConnectionStateCompleted;
655 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
656 return RTCIceConnectionStateFailed;
657 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
658 return RTCIceConnectionStateDisconnected;
659 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
660 return RTCIceConnectionStateClosed;
661 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700662 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800663 }
664}
665
666+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
667 switch (state) {
668 case RTCIceConnectionStateNew:
669 return @"NEW";
670 case RTCIceConnectionStateChecking:
671 return @"CHECKING";
672 case RTCIceConnectionStateConnected:
673 return @"CONNECTED";
674 case RTCIceConnectionStateCompleted:
675 return @"COMPLETED";
676 case RTCIceConnectionStateFailed:
677 return @"FAILED";
678 case RTCIceConnectionStateDisconnected:
679 return @"DISCONNECTED";
680 case RTCIceConnectionStateClosed:
681 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700682 case RTCIceConnectionStateCount:
683 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800684 }
685}
686
687+ (webrtc::PeerConnectionInterface::IceGatheringState)
688 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
689 switch (state) {
690 case RTCIceGatheringStateNew:
691 return webrtc::PeerConnectionInterface::kIceGatheringNew;
692 case RTCIceGatheringStateGathering:
693 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
694 case RTCIceGatheringStateComplete:
695 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
696 }
697}
698
699+ (RTCIceGatheringState)iceGatheringStateForNativeState:
700 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
701 switch (nativeState) {
702 case webrtc::PeerConnectionInterface::kIceGatheringNew:
703 return RTCIceGatheringStateNew;
704 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
705 return RTCIceGatheringStateGathering;
706 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
707 return RTCIceGatheringStateComplete;
708 }
709}
710
711+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
712 switch (state) {
713 case RTCIceGatheringStateNew:
714 return @"NEW";
715 case RTCIceGatheringStateGathering:
716 return @"GATHERING";
717 case RTCIceGatheringStateComplete:
718 return @"COMPLETE";
719 }
720}
721
722+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
723 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
724 switch (level) {
725 case RTCStatsOutputLevelStandard:
726 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
727 case RTCStatsOutputLevelDebug:
728 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
729 }
730}
731
hjonf396f602016-02-11 16:19:06 -0800732- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
733 return _peerConnection;
734}
735
736@end