blob: bea0edebdded0041579920f86f2065df21040bd6 [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) {
magjed63bafd62017-02-27 07:04:25 -0800135 RTCMediaStream *mediaStream =
136 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800137 RTCPeerConnection *peer_connection = peer_connection_;
138 [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 RTCMediaStream *mediaStream =
145 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
146 RTCPeerConnection *peer_connection = peer_connection_;
147 [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) {
153 RTCRtpTransceiver *transceiver =
154 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
155 RTCPeerConnection *peer_connection = peer_connection_;
156 if ([peer_connection.delegate
157 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
158 [peer_connection.delegate peerConnection:peer_connection
159 didStartReceivingOnTransceiver:transceiver];
160 }
161}
162
hjonf396f602016-02-11 16:19:06 -0800163void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700164 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800165 RTCDataChannel *dataChannel =
166 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
167 RTCPeerConnection *peer_connection = peer_connection_;
168 [peer_connection.delegate peerConnection:peer_connection
169 didOpenDataChannel:dataChannel];
170}
171
172void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
173 RTCPeerConnection *peer_connection = peer_connection_;
174 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
175}
176
177void PeerConnectionDelegateAdapter::OnIceConnectionChange(
178 PeerConnectionInterface::IceConnectionState new_state) {
179 RTCIceConnectionState state =
180 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
181 RTCPeerConnection *peer_connection = peer_connection_;
182 [peer_connection.delegate peerConnection:peer_connection
183 didChangeIceConnectionState:state];
184}
185
186void PeerConnectionDelegateAdapter::OnIceGatheringChange(
187 PeerConnectionInterface::IceGatheringState new_state) {
188 RTCIceGatheringState state =
189 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
190 RTCPeerConnection *peer_connection = peer_connection_;
191 [peer_connection.delegate peerConnection:peer_connection
192 didChangeIceGatheringState:state];
193}
194
195void PeerConnectionDelegateAdapter::OnIceCandidate(
196 const IceCandidateInterface *candidate) {
197 RTCIceCandidate *iceCandidate =
198 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
199 RTCPeerConnection *peer_connection = peer_connection_;
200 [peer_connection.delegate peerConnection:peer_connection
201 didGenerateIceCandidate:iceCandidate];
202}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700203
204void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
205 const std::vector<cricket::Candidate>& candidates) {
206 NSMutableArray* ice_candidates =
207 [NSMutableArray arrayWithCapacity:candidates.size()];
208 for (const auto& candidate : candidates) {
209 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
210 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
211 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
212 initWithNativeCandidate:candidate_wrapper.get()];
213 [ice_candidates addObject:ice_candidate];
214 }
215 RTCPeerConnection* peer_connection = peer_connection_;
216 [peer_connection.delegate peerConnection:peer_connection
217 didRemoveIceCandidates:ice_candidates];
218}
219
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300220void PeerConnectionDelegateAdapter::OnAddTrack(
221 rtc::scoped_refptr<RtpReceiverInterface> receiver,
222 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
223 RTCPeerConnection *peer_connection = peer_connection_;
224 if ([peer_connection.delegate
225 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
226 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
227 for (const auto& nativeStream : streams) {
228 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithNativeMediaStream:nativeStream];
229 [mediaStreams addObject:mediaStream];
230 }
231 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:receiver];
232
233 [peer_connection.delegate peerConnection:peer_connection
234 didAddReceiver:rtpReceiver
235 streams:mediaStreams];
236 }
237}
238
hjonf396f602016-02-11 16:19:06 -0800239} // namespace webrtc
240
241
242@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300243 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700244 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700245 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800246 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800247 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700248 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800249}
250
251@synthesize delegate = _delegate;
252
253- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
254 configuration:(RTCConfiguration *)configuration
255 constraints:(RTCMediaConstraints *)constraints
256 delegate:(id<RTCPeerConnectionDelegate>)delegate {
257 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200258 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700259 [configuration createNativeConfiguration]);
260 if (!config) {
261 return nil;
262 }
hjonf396f602016-02-11 16:19:06 -0800263 if (self = [super init]) {
264 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800265 _nativeConstraints = constraints.nativeConstraints;
266 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
267 config.get());
hjonf396f602016-02-11 16:19:06 -0800268 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700269 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700270 nullptr,
271 nullptr,
272 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700273 if (!_peerConnection) {
274 return nil;
275 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300276 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800277 _localStreams = [[NSMutableArray alloc] init];
278 _delegate = delegate;
279 }
280 return self;
281}
282
vopatop.skam96b6b832016-08-18 14:21:20 -0700283- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800284 return [_localStreams copy];
285}
286
287- (RTCSessionDescription *)localDescription {
288 const webrtc::SessionDescriptionInterface *description =
289 _peerConnection->local_description();
290 return description ?
291 [[RTCSessionDescription alloc] initWithNativeDescription:description]
292 : nil;
293}
294
295- (RTCSessionDescription *)remoteDescription {
296 const webrtc::SessionDescriptionInterface *description =
297 _peerConnection->remote_description();
298 return description ?
299 [[RTCSessionDescription alloc] initWithNativeDescription:description]
300 : nil;
301}
302
303- (RTCSignalingState)signalingState {
304 return [[self class]
305 signalingStateForNativeState:_peerConnection->signaling_state()];
306}
307
308- (RTCIceConnectionState)iceConnectionState {
309 return [[self class] iceConnectionStateForNativeState:
310 _peerConnection->ice_connection_state()];
311}
312
313- (RTCIceGatheringState)iceGatheringState {
314 return [[self class] iceGatheringStateForNativeState:
315 _peerConnection->ice_gathering_state()];
316}
317
tkchinaac3eb22016-03-09 21:49:40 -0800318- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200319 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700320 [configuration createNativeConfiguration]);
321 if (!config) {
322 return NO;
323 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800324 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
325 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200326 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800327}
328
jtteh4eeb5372017-04-03 15:06:37 -0700329- (RTCConfiguration *)configuration {
330 webrtc::PeerConnectionInterface::RTCConfiguration config =
331 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700332 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700333}
334
hjonf396f602016-02-11 16:19:06 -0800335- (void)close {
336 _peerConnection->Close();
337}
338
339- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700340 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800341 candidate.nativeCandidate);
342 _peerConnection->AddIceCandidate(iceCandidate.get());
343}
344
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700345- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
346 std::vector<cricket::Candidate> candidates;
347 for (RTCIceCandidate *iceCandidate in iceCandidates) {
348 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
349 iceCandidate.nativeCandidate);
350 if (candidate) {
351 candidates.push_back(candidate->candidate());
352 // Need to fill the transport name from the sdp_mid.
353 candidates.back().set_transport_name(candidate->sdp_mid());
354 }
355 }
356 if (!candidates.empty()) {
357 _peerConnection->RemoveIceCandidates(candidates);
358 }
359}
360
hjonf396f602016-02-11 16:19:06 -0800361- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800362 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800363 RTCLogError(@"Failed to add stream: %@", stream);
364 return;
365 }
366 [_localStreams addObject:stream];
367}
368
369- (void)removeStream:(RTCMediaStream *)stream {
370 _peerConnection->RemoveStream(stream.nativeMediaStream);
371 [_localStreams removeObject:stream];
372}
373
Seth Hampson513449e2018-03-06 09:35:56 -0800374- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
375 std::vector<std::string> nativeStreamIds;
376 for (NSString *streamId in streamIds) {
377 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800378 }
379 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800380 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800381 if (!nativeSenderOrError.ok()) {
382 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
383 return nil;
384 }
385 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
386}
387
388- (BOOL)removeTrack:(RTCRtpSender *)sender {
389 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
390 if (!result) {
391 RTCLogError(@"Failed to remote track %@", sender);
392 }
393 return result;
394}
395
396- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
397 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
398}
399
400- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
401 init:(RTCRtpTransceiverInit *)init {
402 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
403 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
404 if (!nativeTransceiverOrError.ok()) {
405 RTCLogError(
406 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
407 return nil;
408 }
409 return
410 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
411}
412
413- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
414 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
415}
416
417- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
418 init:(RTCRtpTransceiverInit *)init {
419 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
420 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
421 init.nativeInit);
422 if (!nativeTransceiverOrError.ok()) {
423 RTCLogError(@"Failed to add transceiver %@: %s",
424 [RTCRtpReceiver stringForMediaType:mediaType],
425 nativeTransceiverOrError.error().message());
426 return nil;
427 }
428 return
429 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
430}
431
hjonf396f602016-02-11 16:19:06 -0800432- (void)offerForConstraints:(RTCMediaConstraints *)constraints
433 completionHandler:
434 (void (^)(RTCSessionDescription *sessionDescription,
435 NSError *error))completionHandler {
436 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
437 observer(new rtc::RefCountedObject
438 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
439 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
440}
441
442- (void)answerForConstraints:(RTCMediaConstraints *)constraints
443 completionHandler:
444 (void (^)(RTCSessionDescription *sessionDescription,
445 NSError *error))completionHandler {
446 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
447 observer(new rtc::RefCountedObject
448 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
449 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
450}
451
452- (void)setLocalDescription:(RTCSessionDescription *)sdp
453 completionHandler:(void (^)(NSError *error))completionHandler {
454 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
455 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
456 completionHandler));
457 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
458}
459
460- (void)setRemoteDescription:(RTCSessionDescription *)sdp
461 completionHandler:(void (^)(NSError *error))completionHandler {
462 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
463 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
464 completionHandler));
465 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
466}
467
zstein8b476172017-09-05 14:43:03 -0700468- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
469 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
470 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700471 webrtc::PeerConnectionInterface::BitrateParameters params;
472 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200473 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700474 }
475 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200476 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700477 }
478 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200479 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700480 }
481 return _peerConnection->SetBitrate(params).ok();
482}
483
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200484- (void)setBitrateAllocationStrategy:
485 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
486 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
487}
488
ivoc14d5dbe2016-07-04 07:06:55 -0700489- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
490 maxSizeInBytes:(int64_t)maxSizeInBytes {
491 RTC_DCHECK(filePath.length);
492 RTC_DCHECK_GT(maxSizeInBytes, 0);
493 RTC_DCHECK(!_hasStartedRtcEventLog);
494 if (_hasStartedRtcEventLog) {
495 RTCLogError(@"Event logging already started.");
496 return NO;
497 }
498 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
499 S_IRUSR | S_IWUSR);
500 if (fd < 0) {
501 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
502 return NO;
503 }
504 _hasStartedRtcEventLog =
505 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
506 return _hasStartedRtcEventLog;
507}
508
509- (void)stopRtcEventLog {
510 _peerConnection->StopRtcEventLog();
511 _hasStartedRtcEventLog = NO;
512}
513
skvladf3569c82016-04-29 15:30:16 -0700514- (RTCRtpSender *)senderWithKind:(NSString *)kind
515 streamId:(NSString *)streamId {
516 std::string nativeKind = [NSString stdStringForString:kind];
517 std::string nativeStreamId = [NSString stdStringForString:streamId];
518 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
519 _peerConnection->CreateSender(nativeKind, nativeStreamId));
520 return nativeSender ?
521 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
522 : nil;
523}
524
skvlad79b4b872016-04-08 17:28:55 -0700525- (NSArray<RTCRtpSender *> *)senders {
526 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
527 _peerConnection->GetSenders());
528 NSMutableArray *senders = [[NSMutableArray alloc] init];
529 for (const auto &nativeSender : nativeSenders) {
530 RTCRtpSender *sender =
531 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
532 [senders addObject:sender];
533 }
534 return senders;
535}
536
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700537- (NSArray<RTCRtpReceiver *> *)receivers {
538 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
539 _peerConnection->GetReceivers());
540 NSMutableArray *receivers = [[NSMutableArray alloc] init];
541 for (const auto &nativeReceiver : nativeReceivers) {
542 RTCRtpReceiver *receiver =
543 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
544 [receivers addObject:receiver];
545 }
546 return receivers;
547}
548
Steve Anton8cb344a2018-02-27 15:34:53 -0800549- (NSArray<RTCRtpTransceiver *> *)transceivers {
550 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
551 _peerConnection->GetTransceivers());
552 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
553 for (auto nativeTransceiver : nativeTransceivers) {
554 RTCRtpTransceiver *transceiver =
555 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
556 [transceivers addObject:transceiver];
557 }
558 return transceivers;
559}
560
hjonf396f602016-02-11 16:19:06 -0800561#pragma mark - Private
562
563+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
564 (RTCSignalingState)state {
565 switch (state) {
566 case RTCSignalingStateStable:
567 return webrtc::PeerConnectionInterface::kStable;
568 case RTCSignalingStateHaveLocalOffer:
569 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
570 case RTCSignalingStateHaveLocalPrAnswer:
571 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
572 case RTCSignalingStateHaveRemoteOffer:
573 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
574 case RTCSignalingStateHaveRemotePrAnswer:
575 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
576 case RTCSignalingStateClosed:
577 return webrtc::PeerConnectionInterface::kClosed;
578 }
579}
580
581+ (RTCSignalingState)signalingStateForNativeState:
582 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
583 switch (nativeState) {
584 case webrtc::PeerConnectionInterface::kStable:
585 return RTCSignalingStateStable;
586 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
587 return RTCSignalingStateHaveLocalOffer;
588 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
589 return RTCSignalingStateHaveLocalPrAnswer;
590 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
591 return RTCSignalingStateHaveRemoteOffer;
592 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
593 return RTCSignalingStateHaveRemotePrAnswer;
594 case webrtc::PeerConnectionInterface::kClosed:
595 return RTCSignalingStateClosed;
596 }
597}
598
599+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
600 switch (state) {
601 case RTCSignalingStateStable:
602 return @"STABLE";
603 case RTCSignalingStateHaveLocalOffer:
604 return @"HAVE_LOCAL_OFFER";
605 case RTCSignalingStateHaveLocalPrAnswer:
606 return @"HAVE_LOCAL_PRANSWER";
607 case RTCSignalingStateHaveRemoteOffer:
608 return @"HAVE_REMOTE_OFFER";
609 case RTCSignalingStateHaveRemotePrAnswer:
610 return @"HAVE_REMOTE_PRANSWER";
611 case RTCSignalingStateClosed:
612 return @"CLOSED";
613 }
614}
615
616+ (webrtc::PeerConnectionInterface::IceConnectionState)
617 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
618 switch (state) {
619 case RTCIceConnectionStateNew:
620 return webrtc::PeerConnectionInterface::kIceConnectionNew;
621 case RTCIceConnectionStateChecking:
622 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
623 case RTCIceConnectionStateConnected:
624 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
625 case RTCIceConnectionStateCompleted:
626 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
627 case RTCIceConnectionStateFailed:
628 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
629 case RTCIceConnectionStateDisconnected:
630 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
631 case RTCIceConnectionStateClosed:
632 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700633 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800634 return webrtc::PeerConnectionInterface::kIceConnectionMax;
635 }
636}
637
638+ (RTCIceConnectionState)iceConnectionStateForNativeState:
639 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
640 switch (nativeState) {
641 case webrtc::PeerConnectionInterface::kIceConnectionNew:
642 return RTCIceConnectionStateNew;
643 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
644 return RTCIceConnectionStateChecking;
645 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
646 return RTCIceConnectionStateConnected;
647 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
648 return RTCIceConnectionStateCompleted;
649 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
650 return RTCIceConnectionStateFailed;
651 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
652 return RTCIceConnectionStateDisconnected;
653 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
654 return RTCIceConnectionStateClosed;
655 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700656 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800657 }
658}
659
660+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
661 switch (state) {
662 case RTCIceConnectionStateNew:
663 return @"NEW";
664 case RTCIceConnectionStateChecking:
665 return @"CHECKING";
666 case RTCIceConnectionStateConnected:
667 return @"CONNECTED";
668 case RTCIceConnectionStateCompleted:
669 return @"COMPLETED";
670 case RTCIceConnectionStateFailed:
671 return @"FAILED";
672 case RTCIceConnectionStateDisconnected:
673 return @"DISCONNECTED";
674 case RTCIceConnectionStateClosed:
675 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700676 case RTCIceConnectionStateCount:
677 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800678 }
679}
680
681+ (webrtc::PeerConnectionInterface::IceGatheringState)
682 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
683 switch (state) {
684 case RTCIceGatheringStateNew:
685 return webrtc::PeerConnectionInterface::kIceGatheringNew;
686 case RTCIceGatheringStateGathering:
687 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
688 case RTCIceGatheringStateComplete:
689 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
690 }
691}
692
693+ (RTCIceGatheringState)iceGatheringStateForNativeState:
694 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
695 switch (nativeState) {
696 case webrtc::PeerConnectionInterface::kIceGatheringNew:
697 return RTCIceGatheringStateNew;
698 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
699 return RTCIceGatheringStateGathering;
700 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
701 return RTCIceGatheringStateComplete;
702 }
703}
704
705+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
706 switch (state) {
707 case RTCIceGatheringStateNew:
708 return @"NEW";
709 case RTCIceGatheringStateGathering:
710 return @"GATHERING";
711 case RTCIceGatheringStateComplete:
712 return @"COMPLETE";
713 }
714}
715
716+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
717 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
718 switch (level) {
719 case RTCStatsOutputLevelStandard:
720 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
721 case RTCStatsOutputLevelDebug:
722 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
723 }
724}
725
hjonf396f602016-02-11 16:19:06 -0800726- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
727 return _peerConnection;
728}
729
730@end