blob: 103b3c095dcbd23490c304570c2a33df96fd2bdc [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
Mirko Bonadei17aff352018-07-26 12:20:40 +020049 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080050
51 void OnSuccess(SessionDescriptionInterface *desc) override {
52 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070053 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
54 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080055 RTCSessionDescription* session =
56 [[RTCSessionDescription alloc] initWithNativeDescription:
57 description.get()];
58 completion_handler_(session, nil);
59 completion_handler_ = nil;
60 }
61
Harald Alvestrand73771a82018-05-24 10:53:49 +020062 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080063 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020064 // TODO(hta): Add handling of error.type()
65 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080066 NSError* err =
67 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
68 code:kRTCPeerConnnectionSessionDescriptionError
69 userInfo:@{ NSLocalizedDescriptionKey : str }];
70 completion_handler_(nil, err);
71 completion_handler_ = nil;
72 }
73
74 private:
75 void (^completion_handler_)
76 (RTCSessionDescription *sessionDescription, NSError *error);
77};
78
79class SetSessionDescriptionObserverAdapter :
80 public SetSessionDescriptionObserver {
81 public:
82 SetSessionDescriptionObserverAdapter(void (^completionHandler)
83 (NSError *error)) {
84 completion_handler_ = completionHandler;
85 }
86
Mirko Bonadei17aff352018-07-26 12:20:40 +020087 ~SetSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080088
89 void OnSuccess() override {
90 RTC_DCHECK(completion_handler_);
91 completion_handler_(nil);
92 completion_handler_ = nil;
93 }
94
Harald Alvestrand73771a82018-05-24 10:53:49 +020095 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080096 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020097 // TODO(hta): Add handling of error.type()
98 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080099 NSError* err =
100 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
101 code:kRTCPeerConnnectionSessionDescriptionError
102 userInfo:@{ NSLocalizedDescriptionKey : str }];
103 completion_handler_(err);
104 completion_handler_ = nil;
105 }
106
107 private:
108 void (^completion_handler_)(NSError *error);
109};
110
111PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
112 RTCPeerConnection *peerConnection) {
113 peer_connection_ = peerConnection;
114}
115
116PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
117 peer_connection_ = nil;
118}
119
120void PeerConnectionDelegateAdapter::OnSignalingChange(
121 PeerConnectionInterface::SignalingState new_state) {
122 RTCSignalingState state =
123 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
124 RTCPeerConnection *peer_connection = peer_connection_;
125 [peer_connection.delegate peerConnection:peer_connection
126 didChangeSignalingState:state];
127}
128
129void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700130 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800131 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300132 RTCMediaStream *mediaStream =
133 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800134 [peer_connection.delegate peerConnection:peer_connection
135 didAddStream:mediaStream];
136}
137
138void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700139 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800140 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300141 RTCMediaStream *mediaStream =
142 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
143
hjonf396f602016-02-11 16:19:06 -0800144 [peer_connection.delegate peerConnection:peer_connection
145 didRemoveStream:mediaStream];
146}
147
Steve Anton8cb344a2018-02-27 15:34:53 -0800148void PeerConnectionDelegateAdapter::OnTrack(
149 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Steve Anton8cb344a2018-02-27 15:34:53 -0800150 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300151 RTCRtpTransceiver *transceiver =
152 [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory
153 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800154 if ([peer_connection.delegate
155 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
156 [peer_connection.delegate peerConnection:peer_connection
157 didStartReceivingOnTransceiver:transceiver];
158 }
159}
160
hjonf396f602016-02-11 16:19:06 -0800161void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700162 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800163 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300164 RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory
165 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800166 [peer_connection.delegate peerConnection:peer_connection
167 didOpenDataChannel:dataChannel];
168}
169
170void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
171 RTCPeerConnection *peer_connection = peer_connection_;
172 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
173}
174
175void PeerConnectionDelegateAdapter::OnIceConnectionChange(
176 PeerConnectionInterface::IceConnectionState new_state) {
177 RTCIceConnectionState state =
178 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
179 RTCPeerConnection *peer_connection = peer_connection_;
180 [peer_connection.delegate peerConnection:peer_connection
181 didChangeIceConnectionState:state];
182}
183
184void PeerConnectionDelegateAdapter::OnIceGatheringChange(
185 PeerConnectionInterface::IceGatheringState new_state) {
186 RTCIceGatheringState state =
187 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
188 RTCPeerConnection *peer_connection = peer_connection_;
189 [peer_connection.delegate peerConnection:peer_connection
190 didChangeIceGatheringState:state];
191}
192
193void PeerConnectionDelegateAdapter::OnIceCandidate(
194 const IceCandidateInterface *candidate) {
195 RTCIceCandidate *iceCandidate =
196 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
197 RTCPeerConnection *peer_connection = peer_connection_;
198 [peer_connection.delegate peerConnection:peer_connection
199 didGenerateIceCandidate:iceCandidate];
200}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700201
202void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
203 const std::vector<cricket::Candidate>& candidates) {
204 NSMutableArray* ice_candidates =
205 [NSMutableArray arrayWithCapacity:candidates.size()];
206 for (const auto& candidate : candidates) {
207 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
208 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
209 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
210 initWithNativeCandidate:candidate_wrapper.get()];
211 [ice_candidates addObject:ice_candidate];
212 }
213 RTCPeerConnection* peer_connection = peer_connection_;
214 [peer_connection.delegate peerConnection:peer_connection
215 didRemoveIceCandidates:ice_candidates];
216}
217
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300218void PeerConnectionDelegateAdapter::OnAddTrack(
219 rtc::scoped_refptr<RtpReceiverInterface> receiver,
220 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
221 RTCPeerConnection *peer_connection = peer_connection_;
222 if ([peer_connection.delegate
223 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
224 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
225 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300226 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
227 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300228 [mediaStreams addObject:mediaStream];
229 }
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300230 RTCRtpReceiver *rtpReceiver =
231 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300232
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;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300252@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800253
254- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
255 configuration:(RTCConfiguration *)configuration
256 constraints:(RTCMediaConstraints *)constraints
257 delegate:(id<RTCPeerConnectionDelegate>)delegate {
258 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200259 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700260 [configuration createNativeConfiguration]);
261 if (!config) {
262 return nil;
263 }
hjonf396f602016-02-11 16:19:06 -0800264 if (self = [super init]) {
265 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800266 _nativeConstraints = constraints.nativeConstraints;
267 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
268 config.get());
hjonf396f602016-02-11 16:19:06 -0800269 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700270 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700271 nullptr,
272 nullptr,
273 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700274 if (!_peerConnection) {
275 return nil;
276 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300277 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800278 _localStreams = [[NSMutableArray alloc] init];
279 _delegate = delegate;
280 }
281 return self;
282}
283
vopatop.skam96b6b832016-08-18 14:21:20 -0700284- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800285 return [_localStreams copy];
286}
287
288- (RTCSessionDescription *)localDescription {
289 const webrtc::SessionDescriptionInterface *description =
290 _peerConnection->local_description();
291 return description ?
292 [[RTCSessionDescription alloc] initWithNativeDescription:description]
293 : nil;
294}
295
296- (RTCSessionDescription *)remoteDescription {
297 const webrtc::SessionDescriptionInterface *description =
298 _peerConnection->remote_description();
299 return description ?
300 [[RTCSessionDescription alloc] initWithNativeDescription:description]
301 : nil;
302}
303
304- (RTCSignalingState)signalingState {
305 return [[self class]
306 signalingStateForNativeState:_peerConnection->signaling_state()];
307}
308
309- (RTCIceConnectionState)iceConnectionState {
310 return [[self class] iceConnectionStateForNativeState:
311 _peerConnection->ice_connection_state()];
312}
313
314- (RTCIceGatheringState)iceGatheringState {
315 return [[self class] iceGatheringStateForNativeState:
316 _peerConnection->ice_gathering_state()];
317}
318
tkchinaac3eb22016-03-09 21:49:40 -0800319- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200320 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700321 [configuration createNativeConfiguration]);
322 if (!config) {
323 return NO;
324 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800325 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
326 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200327 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800328}
329
jtteh4eeb5372017-04-03 15:06:37 -0700330- (RTCConfiguration *)configuration {
331 webrtc::PeerConnectionInterface::RTCConfiguration config =
332 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700333 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700334}
335
hjonf396f602016-02-11 16:19:06 -0800336- (void)close {
337 _peerConnection->Close();
338}
339
340- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700341 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800342 candidate.nativeCandidate);
343 _peerConnection->AddIceCandidate(iceCandidate.get());
344}
345
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700346- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
347 std::vector<cricket::Candidate> candidates;
348 for (RTCIceCandidate *iceCandidate in iceCandidates) {
349 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
350 iceCandidate.nativeCandidate);
351 if (candidate) {
352 candidates.push_back(candidate->candidate());
353 // Need to fill the transport name from the sdp_mid.
354 candidates.back().set_transport_name(candidate->sdp_mid());
355 }
356 }
357 if (!candidates.empty()) {
358 _peerConnection->RemoveIceCandidates(candidates);
359 }
360}
361
hjonf396f602016-02-11 16:19:06 -0800362- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800363 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800364 RTCLogError(@"Failed to add stream: %@", stream);
365 return;
366 }
367 [_localStreams addObject:stream];
368}
369
370- (void)removeStream:(RTCMediaStream *)stream {
371 _peerConnection->RemoveStream(stream.nativeMediaStream);
372 [_localStreams removeObject:stream];
373}
374
Seth Hampson513449e2018-03-06 09:35:56 -0800375- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
376 std::vector<std::string> nativeStreamIds;
377 for (NSString *streamId in streamIds) {
378 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800379 }
380 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800381 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800382 if (!nativeSenderOrError.ok()) {
383 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
384 return nil;
385 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300386 return [[RTCRtpSender alloc] initWithFactory:self.factory
387 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800388}
389
390- (BOOL)removeTrack:(RTCRtpSender *)sender {
391 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
392 if (!result) {
393 RTCLogError(@"Failed to remote track %@", sender);
394 }
395 return result;
396}
397
398- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
399 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
400}
401
402- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
403 init:(RTCRtpTransceiverInit *)init {
404 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
405 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
406 if (!nativeTransceiverOrError.ok()) {
407 RTCLogError(
408 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
409 return nil;
410 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300411 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
412 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800413}
414
415- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
416 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
417}
418
419- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
420 init:(RTCRtpTransceiverInit *)init {
421 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
422 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
423 init.nativeInit);
424 if (!nativeTransceiverOrError.ok()) {
425 RTCLogError(@"Failed to add transceiver %@: %s",
426 [RTCRtpReceiver stringForMediaType:mediaType],
427 nativeTransceiverOrError.error().message());
428 return nil;
429 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300430 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
431 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800432}
433
hjonf396f602016-02-11 16:19:06 -0800434- (void)offerForConstraints:(RTCMediaConstraints *)constraints
435 completionHandler:
436 (void (^)(RTCSessionDescription *sessionDescription,
437 NSError *error))completionHandler {
438 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
439 observer(new rtc::RefCountedObject
440 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
441 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
442}
443
444- (void)answerForConstraints:(RTCMediaConstraints *)constraints
445 completionHandler:
446 (void (^)(RTCSessionDescription *sessionDescription,
447 NSError *error))completionHandler {
448 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
449 observer(new rtc::RefCountedObject
450 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
451 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
452}
453
454- (void)setLocalDescription:(RTCSessionDescription *)sdp
455 completionHandler:(void (^)(NSError *error))completionHandler {
456 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
457 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
458 completionHandler));
459 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
460}
461
462- (void)setRemoteDescription:(RTCSessionDescription *)sdp
463 completionHandler:(void (^)(NSError *error))completionHandler {
464 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
465 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
466 completionHandler));
467 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
468}
469
zstein8b476172017-09-05 14:43:03 -0700470- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
471 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
472 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700473 webrtc::PeerConnectionInterface::BitrateParameters params;
474 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200475 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700476 }
477 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200478 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700479 }
480 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200481 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700482 }
483 return _peerConnection->SetBitrate(params).ok();
484}
485
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200486- (void)setBitrateAllocationStrategy:
487 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
488 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
489}
490
ivoc14d5dbe2016-07-04 07:06:55 -0700491- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
492 maxSizeInBytes:(int64_t)maxSizeInBytes {
493 RTC_DCHECK(filePath.length);
494 RTC_DCHECK_GT(maxSizeInBytes, 0);
495 RTC_DCHECK(!_hasStartedRtcEventLog);
496 if (_hasStartedRtcEventLog) {
497 RTCLogError(@"Event logging already started.");
498 return NO;
499 }
500 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
501 S_IRUSR | S_IWUSR);
502 if (fd < 0) {
503 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
504 return NO;
505 }
506 _hasStartedRtcEventLog =
507 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
508 return _hasStartedRtcEventLog;
509}
510
511- (void)stopRtcEventLog {
512 _peerConnection->StopRtcEventLog();
513 _hasStartedRtcEventLog = NO;
514}
515
skvladf3569c82016-04-29 15:30:16 -0700516- (RTCRtpSender *)senderWithKind:(NSString *)kind
517 streamId:(NSString *)streamId {
518 std::string nativeKind = [NSString stdStringForString:kind];
519 std::string nativeStreamId = [NSString stdStringForString:streamId];
520 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
521 _peerConnection->CreateSender(nativeKind, nativeStreamId));
522 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300523 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
524 nil;
skvladf3569c82016-04-29 15:30:16 -0700525}
526
skvlad79b4b872016-04-08 17:28:55 -0700527- (NSArray<RTCRtpSender *> *)senders {
528 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
529 _peerConnection->GetSenders());
530 NSMutableArray *senders = [[NSMutableArray alloc] init];
531 for (const auto &nativeSender : nativeSenders) {
532 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300533 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700534 [senders addObject:sender];
535 }
536 return senders;
537}
538
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700539- (NSArray<RTCRtpReceiver *> *)receivers {
540 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
541 _peerConnection->GetReceivers());
542 NSMutableArray *receivers = [[NSMutableArray alloc] init];
543 for (const auto &nativeReceiver : nativeReceivers) {
544 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300545 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700546 [receivers addObject:receiver];
547 }
548 return receivers;
549}
550
Steve Anton8cb344a2018-02-27 15:34:53 -0800551- (NSArray<RTCRtpTransceiver *> *)transceivers {
552 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
553 _peerConnection->GetTransceivers());
554 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
555 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300556 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
557 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800558 [transceivers addObject:transceiver];
559 }
560 return transceivers;
561}
562
hjonf396f602016-02-11 16:19:06 -0800563#pragma mark - Private
564
565+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
566 (RTCSignalingState)state {
567 switch (state) {
568 case RTCSignalingStateStable:
569 return webrtc::PeerConnectionInterface::kStable;
570 case RTCSignalingStateHaveLocalOffer:
571 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
572 case RTCSignalingStateHaveLocalPrAnswer:
573 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
574 case RTCSignalingStateHaveRemoteOffer:
575 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
576 case RTCSignalingStateHaveRemotePrAnswer:
577 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
578 case RTCSignalingStateClosed:
579 return webrtc::PeerConnectionInterface::kClosed;
580 }
581}
582
583+ (RTCSignalingState)signalingStateForNativeState:
584 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
585 switch (nativeState) {
586 case webrtc::PeerConnectionInterface::kStable:
587 return RTCSignalingStateStable;
588 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
589 return RTCSignalingStateHaveLocalOffer;
590 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
591 return RTCSignalingStateHaveLocalPrAnswer;
592 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
593 return RTCSignalingStateHaveRemoteOffer;
594 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
595 return RTCSignalingStateHaveRemotePrAnswer;
596 case webrtc::PeerConnectionInterface::kClosed:
597 return RTCSignalingStateClosed;
598 }
599}
600
601+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
602 switch (state) {
603 case RTCSignalingStateStable:
604 return @"STABLE";
605 case RTCSignalingStateHaveLocalOffer:
606 return @"HAVE_LOCAL_OFFER";
607 case RTCSignalingStateHaveLocalPrAnswer:
608 return @"HAVE_LOCAL_PRANSWER";
609 case RTCSignalingStateHaveRemoteOffer:
610 return @"HAVE_REMOTE_OFFER";
611 case RTCSignalingStateHaveRemotePrAnswer:
612 return @"HAVE_REMOTE_PRANSWER";
613 case RTCSignalingStateClosed:
614 return @"CLOSED";
615 }
616}
617
618+ (webrtc::PeerConnectionInterface::IceConnectionState)
619 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
620 switch (state) {
621 case RTCIceConnectionStateNew:
622 return webrtc::PeerConnectionInterface::kIceConnectionNew;
623 case RTCIceConnectionStateChecking:
624 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
625 case RTCIceConnectionStateConnected:
626 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
627 case RTCIceConnectionStateCompleted:
628 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
629 case RTCIceConnectionStateFailed:
630 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
631 case RTCIceConnectionStateDisconnected:
632 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
633 case RTCIceConnectionStateClosed:
634 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700635 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800636 return webrtc::PeerConnectionInterface::kIceConnectionMax;
637 }
638}
639
640+ (RTCIceConnectionState)iceConnectionStateForNativeState:
641 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
642 switch (nativeState) {
643 case webrtc::PeerConnectionInterface::kIceConnectionNew:
644 return RTCIceConnectionStateNew;
645 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
646 return RTCIceConnectionStateChecking;
647 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
648 return RTCIceConnectionStateConnected;
649 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
650 return RTCIceConnectionStateCompleted;
651 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
652 return RTCIceConnectionStateFailed;
653 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
654 return RTCIceConnectionStateDisconnected;
655 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
656 return RTCIceConnectionStateClosed;
657 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700658 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800659 }
660}
661
662+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
663 switch (state) {
664 case RTCIceConnectionStateNew:
665 return @"NEW";
666 case RTCIceConnectionStateChecking:
667 return @"CHECKING";
668 case RTCIceConnectionStateConnected:
669 return @"CONNECTED";
670 case RTCIceConnectionStateCompleted:
671 return @"COMPLETED";
672 case RTCIceConnectionStateFailed:
673 return @"FAILED";
674 case RTCIceConnectionStateDisconnected:
675 return @"DISCONNECTED";
676 case RTCIceConnectionStateClosed:
677 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700678 case RTCIceConnectionStateCount:
679 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800680 }
681}
682
683+ (webrtc::PeerConnectionInterface::IceGatheringState)
684 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
685 switch (state) {
686 case RTCIceGatheringStateNew:
687 return webrtc::PeerConnectionInterface::kIceGatheringNew;
688 case RTCIceGatheringStateGathering:
689 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
690 case RTCIceGatheringStateComplete:
691 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
692 }
693}
694
695+ (RTCIceGatheringState)iceGatheringStateForNativeState:
696 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
697 switch (nativeState) {
698 case webrtc::PeerConnectionInterface::kIceGatheringNew:
699 return RTCIceGatheringStateNew;
700 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
701 return RTCIceGatheringStateGathering;
702 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
703 return RTCIceGatheringStateComplete;
704 }
705}
706
707+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
708 switch (state) {
709 case RTCIceGatheringStateNew:
710 return @"NEW";
711 case RTCIceGatheringStateGathering:
712 return @"GATHERING";
713 case RTCIceGatheringStateComplete:
714 return @"COMPLETE";
715 }
716}
717
718+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
719 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
720 switch (level) {
721 case RTCStatsOutputLevelStandard:
722 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
723 case RTCStatsOutputLevelDebug:
724 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
725 }
726}
727
hjonf396f602016-02-11 16:19:06 -0800728- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
729 return _peerConnection;
730}
731
732@end