blob: 8d10c34b6eef7128543a44dc6677f61e1173c121 [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) {
154 RTCRtpTransceiver *transceiver =
155 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
156 RTCPeerConnection *peer_connection = peer_connection_;
157 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 RTCDataChannel *dataChannel =
167 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
168 RTCPeerConnection *peer_connection = peer_connection_;
169 [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) {
180 RTCIceConnectionState state =
181 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
182 RTCPeerConnection *peer_connection = peer_connection_;
183 [peer_connection.delegate peerConnection:peer_connection
184 didChangeIceConnectionState:state];
185}
186
187void PeerConnectionDelegateAdapter::OnIceGatheringChange(
188 PeerConnectionInterface::IceGatheringState new_state) {
189 RTCIceGatheringState state =
190 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
191 RTCPeerConnection *peer_connection = peer_connection_;
192 [peer_connection.delegate peerConnection:peer_connection
193 didChangeIceGatheringState:state];
194}
195
196void PeerConnectionDelegateAdapter::OnIceCandidate(
197 const IceCandidateInterface *candidate) {
198 RTCIceCandidate *iceCandidate =
199 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
200 RTCPeerConnection *peer_connection = peer_connection_;
201 [peer_connection.delegate peerConnection:peer_connection
202 didGenerateIceCandidate:iceCandidate];
203}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700204
205void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
206 const std::vector<cricket::Candidate>& candidates) {
207 NSMutableArray* ice_candidates =
208 [NSMutableArray arrayWithCapacity:candidates.size()];
209 for (const auto& candidate : candidates) {
210 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
211 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
212 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
213 initWithNativeCandidate:candidate_wrapper.get()];
214 [ice_candidates addObject:ice_candidate];
215 }
216 RTCPeerConnection* peer_connection = peer_connection_;
217 [peer_connection.delegate peerConnection:peer_connection
218 didRemoveIceCandidates:ice_candidates];
219}
220
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300221void PeerConnectionDelegateAdapter::OnAddTrack(
222 rtc::scoped_refptr<RtpReceiverInterface> receiver,
223 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
224 RTCPeerConnection *peer_connection = peer_connection_;
225 if ([peer_connection.delegate
226 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
227 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
228 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300229 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
230 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300231 [mediaStreams addObject:mediaStream];
232 }
233 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:receiver];
234
235 [peer_connection.delegate peerConnection:peer_connection
236 didAddReceiver:rtpReceiver
237 streams:mediaStreams];
238 }
239}
240
hjonf396f602016-02-11 16:19:06 -0800241} // namespace webrtc
242
243
244@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300245 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700246 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700247 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800248 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800249 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700250 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800251}
252
253@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300254@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800255
256- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
257 configuration:(RTCConfiguration *)configuration
258 constraints:(RTCMediaConstraints *)constraints
259 delegate:(id<RTCPeerConnectionDelegate>)delegate {
260 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200261 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700262 [configuration createNativeConfiguration]);
263 if (!config) {
264 return nil;
265 }
hjonf396f602016-02-11 16:19:06 -0800266 if (self = [super init]) {
267 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800268 _nativeConstraints = constraints.nativeConstraints;
269 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
270 config.get());
hjonf396f602016-02-11 16:19:06 -0800271 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700272 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700273 nullptr,
274 nullptr,
275 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700276 if (!_peerConnection) {
277 return nil;
278 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300279 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800280 _localStreams = [[NSMutableArray alloc] init];
281 _delegate = delegate;
282 }
283 return self;
284}
285
vopatop.skam96b6b832016-08-18 14:21:20 -0700286- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800287 return [_localStreams copy];
288}
289
290- (RTCSessionDescription *)localDescription {
291 const webrtc::SessionDescriptionInterface *description =
292 _peerConnection->local_description();
293 return description ?
294 [[RTCSessionDescription alloc] initWithNativeDescription:description]
295 : nil;
296}
297
298- (RTCSessionDescription *)remoteDescription {
299 const webrtc::SessionDescriptionInterface *description =
300 _peerConnection->remote_description();
301 return description ?
302 [[RTCSessionDescription alloc] initWithNativeDescription:description]
303 : nil;
304}
305
306- (RTCSignalingState)signalingState {
307 return [[self class]
308 signalingStateForNativeState:_peerConnection->signaling_state()];
309}
310
311- (RTCIceConnectionState)iceConnectionState {
312 return [[self class] iceConnectionStateForNativeState:
313 _peerConnection->ice_connection_state()];
314}
315
316- (RTCIceGatheringState)iceGatheringState {
317 return [[self class] iceGatheringStateForNativeState:
318 _peerConnection->ice_gathering_state()];
319}
320
tkchinaac3eb22016-03-09 21:49:40 -0800321- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200322 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700323 [configuration createNativeConfiguration]);
324 if (!config) {
325 return NO;
326 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800327 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
328 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200329 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800330}
331
jtteh4eeb5372017-04-03 15:06:37 -0700332- (RTCConfiguration *)configuration {
333 webrtc::PeerConnectionInterface::RTCConfiguration config =
334 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700335 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700336}
337
hjonf396f602016-02-11 16:19:06 -0800338- (void)close {
339 _peerConnection->Close();
340}
341
342- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700343 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800344 candidate.nativeCandidate);
345 _peerConnection->AddIceCandidate(iceCandidate.get());
346}
347
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700348- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
349 std::vector<cricket::Candidate> candidates;
350 for (RTCIceCandidate *iceCandidate in iceCandidates) {
351 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
352 iceCandidate.nativeCandidate);
353 if (candidate) {
354 candidates.push_back(candidate->candidate());
355 // Need to fill the transport name from the sdp_mid.
356 candidates.back().set_transport_name(candidate->sdp_mid());
357 }
358 }
359 if (!candidates.empty()) {
360 _peerConnection->RemoveIceCandidates(candidates);
361 }
362}
363
hjonf396f602016-02-11 16:19:06 -0800364- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800365 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800366 RTCLogError(@"Failed to add stream: %@", stream);
367 return;
368 }
369 [_localStreams addObject:stream];
370}
371
372- (void)removeStream:(RTCMediaStream *)stream {
373 _peerConnection->RemoveStream(stream.nativeMediaStream);
374 [_localStreams removeObject:stream];
375}
376
Seth Hampson513449e2018-03-06 09:35:56 -0800377- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
378 std::vector<std::string> nativeStreamIds;
379 for (NSString *streamId in streamIds) {
380 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800381 }
382 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800383 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800384 if (!nativeSenderOrError.ok()) {
385 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
386 return nil;
387 }
388 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
389}
390
391- (BOOL)removeTrack:(RTCRtpSender *)sender {
392 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
393 if (!result) {
394 RTCLogError(@"Failed to remote track %@", sender);
395 }
396 return result;
397}
398
399- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
400 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
401}
402
403- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
404 init:(RTCRtpTransceiverInit *)init {
405 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
406 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
407 if (!nativeTransceiverOrError.ok()) {
408 RTCLogError(
409 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
410 return nil;
411 }
412 return
413 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
414}
415
416- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
417 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
418}
419
420- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
421 init:(RTCRtpTransceiverInit *)init {
422 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
423 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
424 init.nativeInit);
425 if (!nativeTransceiverOrError.ok()) {
426 RTCLogError(@"Failed to add transceiver %@: %s",
427 [RTCRtpReceiver stringForMediaType:mediaType],
428 nativeTransceiverOrError.error().message());
429 return nil;
430 }
431 return
432 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
433}
434
hjonf396f602016-02-11 16:19:06 -0800435- (void)offerForConstraints:(RTCMediaConstraints *)constraints
436 completionHandler:
437 (void (^)(RTCSessionDescription *sessionDescription,
438 NSError *error))completionHandler {
439 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
440 observer(new rtc::RefCountedObject
441 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
442 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
443}
444
445- (void)answerForConstraints:(RTCMediaConstraints *)constraints
446 completionHandler:
447 (void (^)(RTCSessionDescription *sessionDescription,
448 NSError *error))completionHandler {
449 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
450 observer(new rtc::RefCountedObject
451 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
452 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
453}
454
455- (void)setLocalDescription:(RTCSessionDescription *)sdp
456 completionHandler:(void (^)(NSError *error))completionHandler {
457 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
458 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
459 completionHandler));
460 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
461}
462
463- (void)setRemoteDescription:(RTCSessionDescription *)sdp
464 completionHandler:(void (^)(NSError *error))completionHandler {
465 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
466 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
467 completionHandler));
468 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
469}
470
zstein8b476172017-09-05 14:43:03 -0700471- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
472 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
473 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700474 webrtc::PeerConnectionInterface::BitrateParameters params;
475 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200476 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700477 }
478 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200479 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700480 }
481 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200482 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700483 }
484 return _peerConnection->SetBitrate(params).ok();
485}
486
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200487- (void)setBitrateAllocationStrategy:
488 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
489 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
490}
491
ivoc14d5dbe2016-07-04 07:06:55 -0700492- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
493 maxSizeInBytes:(int64_t)maxSizeInBytes {
494 RTC_DCHECK(filePath.length);
495 RTC_DCHECK_GT(maxSizeInBytes, 0);
496 RTC_DCHECK(!_hasStartedRtcEventLog);
497 if (_hasStartedRtcEventLog) {
498 RTCLogError(@"Event logging already started.");
499 return NO;
500 }
501 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
502 S_IRUSR | S_IWUSR);
503 if (fd < 0) {
504 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
505 return NO;
506 }
507 _hasStartedRtcEventLog =
508 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
509 return _hasStartedRtcEventLog;
510}
511
512- (void)stopRtcEventLog {
513 _peerConnection->StopRtcEventLog();
514 _hasStartedRtcEventLog = NO;
515}
516
skvladf3569c82016-04-29 15:30:16 -0700517- (RTCRtpSender *)senderWithKind:(NSString *)kind
518 streamId:(NSString *)streamId {
519 std::string nativeKind = [NSString stdStringForString:kind];
520 std::string nativeStreamId = [NSString stdStringForString:streamId];
521 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
522 _peerConnection->CreateSender(nativeKind, nativeStreamId));
523 return nativeSender ?
524 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
525 : nil;
526}
527
skvlad79b4b872016-04-08 17:28:55 -0700528- (NSArray<RTCRtpSender *> *)senders {
529 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
530 _peerConnection->GetSenders());
531 NSMutableArray *senders = [[NSMutableArray alloc] init];
532 for (const auto &nativeSender : nativeSenders) {
533 RTCRtpSender *sender =
534 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
535 [senders addObject:sender];
536 }
537 return senders;
538}
539
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700540- (NSArray<RTCRtpReceiver *> *)receivers {
541 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
542 _peerConnection->GetReceivers());
543 NSMutableArray *receivers = [[NSMutableArray alloc] init];
544 for (const auto &nativeReceiver : nativeReceivers) {
545 RTCRtpReceiver *receiver =
546 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
547 [receivers addObject:receiver];
548 }
549 return receivers;
550}
551
Steve Anton8cb344a2018-02-27 15:34:53 -0800552- (NSArray<RTCRtpTransceiver *> *)transceivers {
553 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
554 _peerConnection->GetTransceivers());
555 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
556 for (auto nativeTransceiver : nativeTransceivers) {
557 RTCRtpTransceiver *transceiver =
558 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
559 [transceivers addObject:transceiver];
560 }
561 return transceivers;
562}
563
hjonf396f602016-02-11 16:19:06 -0800564#pragma mark - Private
565
566+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
567 (RTCSignalingState)state {
568 switch (state) {
569 case RTCSignalingStateStable:
570 return webrtc::PeerConnectionInterface::kStable;
571 case RTCSignalingStateHaveLocalOffer:
572 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
573 case RTCSignalingStateHaveLocalPrAnswer:
574 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
575 case RTCSignalingStateHaveRemoteOffer:
576 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
577 case RTCSignalingStateHaveRemotePrAnswer:
578 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
579 case RTCSignalingStateClosed:
580 return webrtc::PeerConnectionInterface::kClosed;
581 }
582}
583
584+ (RTCSignalingState)signalingStateForNativeState:
585 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
586 switch (nativeState) {
587 case webrtc::PeerConnectionInterface::kStable:
588 return RTCSignalingStateStable;
589 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
590 return RTCSignalingStateHaveLocalOffer;
591 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
592 return RTCSignalingStateHaveLocalPrAnswer;
593 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
594 return RTCSignalingStateHaveRemoteOffer;
595 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
596 return RTCSignalingStateHaveRemotePrAnswer;
597 case webrtc::PeerConnectionInterface::kClosed:
598 return RTCSignalingStateClosed;
599 }
600}
601
602+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
603 switch (state) {
604 case RTCSignalingStateStable:
605 return @"STABLE";
606 case RTCSignalingStateHaveLocalOffer:
607 return @"HAVE_LOCAL_OFFER";
608 case RTCSignalingStateHaveLocalPrAnswer:
609 return @"HAVE_LOCAL_PRANSWER";
610 case RTCSignalingStateHaveRemoteOffer:
611 return @"HAVE_REMOTE_OFFER";
612 case RTCSignalingStateHaveRemotePrAnswer:
613 return @"HAVE_REMOTE_PRANSWER";
614 case RTCSignalingStateClosed:
615 return @"CLOSED";
616 }
617}
618
619+ (webrtc::PeerConnectionInterface::IceConnectionState)
620 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
621 switch (state) {
622 case RTCIceConnectionStateNew:
623 return webrtc::PeerConnectionInterface::kIceConnectionNew;
624 case RTCIceConnectionStateChecking:
625 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
626 case RTCIceConnectionStateConnected:
627 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
628 case RTCIceConnectionStateCompleted:
629 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
630 case RTCIceConnectionStateFailed:
631 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
632 case RTCIceConnectionStateDisconnected:
633 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
634 case RTCIceConnectionStateClosed:
635 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700636 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800637 return webrtc::PeerConnectionInterface::kIceConnectionMax;
638 }
639}
640
641+ (RTCIceConnectionState)iceConnectionStateForNativeState:
642 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
643 switch (nativeState) {
644 case webrtc::PeerConnectionInterface::kIceConnectionNew:
645 return RTCIceConnectionStateNew;
646 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
647 return RTCIceConnectionStateChecking;
648 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
649 return RTCIceConnectionStateConnected;
650 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
651 return RTCIceConnectionStateCompleted;
652 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
653 return RTCIceConnectionStateFailed;
654 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
655 return RTCIceConnectionStateDisconnected;
656 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
657 return RTCIceConnectionStateClosed;
658 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700659 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800660 }
661}
662
663+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
664 switch (state) {
665 case RTCIceConnectionStateNew:
666 return @"NEW";
667 case RTCIceConnectionStateChecking:
668 return @"CHECKING";
669 case RTCIceConnectionStateConnected:
670 return @"CONNECTED";
671 case RTCIceConnectionStateCompleted:
672 return @"COMPLETED";
673 case RTCIceConnectionStateFailed:
674 return @"FAILED";
675 case RTCIceConnectionStateDisconnected:
676 return @"DISCONNECTED";
677 case RTCIceConnectionStateClosed:
678 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700679 case RTCIceConnectionStateCount:
680 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800681 }
682}
683
684+ (webrtc::PeerConnectionInterface::IceGatheringState)
685 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
686 switch (state) {
687 case RTCIceGatheringStateNew:
688 return webrtc::PeerConnectionInterface::kIceGatheringNew;
689 case RTCIceGatheringStateGathering:
690 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
691 case RTCIceGatheringStateComplete:
692 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
693 }
694}
695
696+ (RTCIceGatheringState)iceGatheringStateForNativeState:
697 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
698 switch (nativeState) {
699 case webrtc::PeerConnectionInterface::kIceGatheringNew:
700 return RTCIceGatheringStateNew;
701 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
702 return RTCIceGatheringStateGathering;
703 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
704 return RTCIceGatheringStateComplete;
705 }
706}
707
708+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
709 switch (state) {
710 case RTCIceGatheringStateNew:
711 return @"NEW";
712 case RTCIceGatheringStateGathering:
713 return @"GATHERING";
714 case RTCIceGatheringStateComplete:
715 return @"COMPLETE";
716 }
717}
718
719+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
720 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
721 switch (level) {
722 case RTCStatsOutputLevelStandard:
723 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
724 case RTCStatsOutputLevelDebug:
725 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
726 }
727}
728
hjonf396f602016-02-11 16:19:06 -0800729- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
730 return _peerConnection;
731}
732
733@end