blob: 11c3a6d5e531f1a6baabd6ffe211d3404f9f2ccc [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
Zeke Chin8de502b2018-08-21 11:41:07 -0700239void PeerConnectionDelegateAdapter::OnRemoveTrack(
240 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
241 RTCPeerConnection *peer_connection = peer_connection_;
242 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
243 RTCRtpReceiver *rtpReceiver =
244 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
245 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
246 }
247}
248
hjonf396f602016-02-11 16:19:06 -0800249} // namespace webrtc
250
251
252@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300253 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700254 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700255 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800256 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800257 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700258 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800259}
260
261@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300262@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800263
264- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
265 configuration:(RTCConfiguration *)configuration
266 constraints:(RTCMediaConstraints *)constraints
267 delegate:(id<RTCPeerConnectionDelegate>)delegate {
268 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200269 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700270 [configuration createNativeConfiguration]);
271 if (!config) {
272 return nil;
273 }
hjonf396f602016-02-11 16:19:06 -0800274 if (self = [super init]) {
275 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800276 _nativeConstraints = constraints.nativeConstraints;
277 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
278 config.get());
hjonf396f602016-02-11 16:19:06 -0800279 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700280 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700281 nullptr,
282 nullptr,
283 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700284 if (!_peerConnection) {
285 return nil;
286 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300287 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800288 _localStreams = [[NSMutableArray alloc] init];
289 _delegate = delegate;
290 }
291 return self;
292}
293
vopatop.skam96b6b832016-08-18 14:21:20 -0700294- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800295 return [_localStreams copy];
296}
297
298- (RTCSessionDescription *)localDescription {
299 const webrtc::SessionDescriptionInterface *description =
300 _peerConnection->local_description();
301 return description ?
302 [[RTCSessionDescription alloc] initWithNativeDescription:description]
303 : nil;
304}
305
306- (RTCSessionDescription *)remoteDescription {
307 const webrtc::SessionDescriptionInterface *description =
308 _peerConnection->remote_description();
309 return description ?
310 [[RTCSessionDescription alloc] initWithNativeDescription:description]
311 : nil;
312}
313
314- (RTCSignalingState)signalingState {
315 return [[self class]
316 signalingStateForNativeState:_peerConnection->signaling_state()];
317}
318
319- (RTCIceConnectionState)iceConnectionState {
320 return [[self class] iceConnectionStateForNativeState:
321 _peerConnection->ice_connection_state()];
322}
323
324- (RTCIceGatheringState)iceGatheringState {
325 return [[self class] iceGatheringStateForNativeState:
326 _peerConnection->ice_gathering_state()];
327}
328
tkchinaac3eb22016-03-09 21:49:40 -0800329- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200330 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700331 [configuration createNativeConfiguration]);
332 if (!config) {
333 return NO;
334 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800335 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
336 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200337 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800338}
339
jtteh4eeb5372017-04-03 15:06:37 -0700340- (RTCConfiguration *)configuration {
341 webrtc::PeerConnectionInterface::RTCConfiguration config =
342 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700343 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700344}
345
hjonf396f602016-02-11 16:19:06 -0800346- (void)close {
347 _peerConnection->Close();
348}
349
350- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700351 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800352 candidate.nativeCandidate);
353 _peerConnection->AddIceCandidate(iceCandidate.get());
354}
355
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700356- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
357 std::vector<cricket::Candidate> candidates;
358 for (RTCIceCandidate *iceCandidate in iceCandidates) {
359 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
360 iceCandidate.nativeCandidate);
361 if (candidate) {
362 candidates.push_back(candidate->candidate());
363 // Need to fill the transport name from the sdp_mid.
364 candidates.back().set_transport_name(candidate->sdp_mid());
365 }
366 }
367 if (!candidates.empty()) {
368 _peerConnection->RemoveIceCandidates(candidates);
369 }
370}
371
hjonf396f602016-02-11 16:19:06 -0800372- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800373 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800374 RTCLogError(@"Failed to add stream: %@", stream);
375 return;
376 }
377 [_localStreams addObject:stream];
378}
379
380- (void)removeStream:(RTCMediaStream *)stream {
381 _peerConnection->RemoveStream(stream.nativeMediaStream);
382 [_localStreams removeObject:stream];
383}
384
Seth Hampson513449e2018-03-06 09:35:56 -0800385- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
386 std::vector<std::string> nativeStreamIds;
387 for (NSString *streamId in streamIds) {
388 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800389 }
390 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800391 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800392 if (!nativeSenderOrError.ok()) {
393 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
394 return nil;
395 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300396 return [[RTCRtpSender alloc] initWithFactory:self.factory
397 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800398}
399
400- (BOOL)removeTrack:(RTCRtpSender *)sender {
401 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
402 if (!result) {
403 RTCLogError(@"Failed to remote track %@", sender);
404 }
405 return result;
406}
407
408- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
409 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
410}
411
412- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
413 init:(RTCRtpTransceiverInit *)init {
414 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
415 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
416 if (!nativeTransceiverOrError.ok()) {
417 RTCLogError(
418 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
419 return nil;
420 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300421 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
422 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800423}
424
425- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
426 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
427}
428
429- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
430 init:(RTCRtpTransceiverInit *)init {
431 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
432 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
433 init.nativeInit);
434 if (!nativeTransceiverOrError.ok()) {
435 RTCLogError(@"Failed to add transceiver %@: %s",
436 [RTCRtpReceiver stringForMediaType:mediaType],
437 nativeTransceiverOrError.error().message());
438 return nil;
439 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300440 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
441 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800442}
443
hjonf396f602016-02-11 16:19:06 -0800444- (void)offerForConstraints:(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));
Niels Möllerf06f9232018-08-07 12:32:18 +0200451 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
452 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
453
454 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800455}
456
457- (void)answerForConstraints:(RTCMediaConstraints *)constraints
458 completionHandler:
459 (void (^)(RTCSessionDescription *sessionDescription,
460 NSError *error))completionHandler {
461 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
462 observer(new rtc::RefCountedObject
463 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200464 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
465 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
466
467 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800468}
469
470- (void)setLocalDescription:(RTCSessionDescription *)sdp
471 completionHandler:(void (^)(NSError *error))completionHandler {
472 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
473 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
474 completionHandler));
475 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
476}
477
478- (void)setRemoteDescription:(RTCSessionDescription *)sdp
479 completionHandler:(void (^)(NSError *error))completionHandler {
480 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
481 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
482 completionHandler));
483 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
484}
485
zstein8b476172017-09-05 14:43:03 -0700486- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
487 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
488 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700489 webrtc::PeerConnectionInterface::BitrateParameters params;
490 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200491 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700492 }
493 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200494 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700495 }
496 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200497 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700498 }
499 return _peerConnection->SetBitrate(params).ok();
500}
501
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200502- (void)setBitrateAllocationStrategy:
503 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
504 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
505}
506
ivoc14d5dbe2016-07-04 07:06:55 -0700507- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
508 maxSizeInBytes:(int64_t)maxSizeInBytes {
509 RTC_DCHECK(filePath.length);
510 RTC_DCHECK_GT(maxSizeInBytes, 0);
511 RTC_DCHECK(!_hasStartedRtcEventLog);
512 if (_hasStartedRtcEventLog) {
513 RTCLogError(@"Event logging already started.");
514 return NO;
515 }
516 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
517 S_IRUSR | S_IWUSR);
518 if (fd < 0) {
519 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
520 return NO;
521 }
522 _hasStartedRtcEventLog =
523 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
524 return _hasStartedRtcEventLog;
525}
526
527- (void)stopRtcEventLog {
528 _peerConnection->StopRtcEventLog();
529 _hasStartedRtcEventLog = NO;
530}
531
skvladf3569c82016-04-29 15:30:16 -0700532- (RTCRtpSender *)senderWithKind:(NSString *)kind
533 streamId:(NSString *)streamId {
534 std::string nativeKind = [NSString stdStringForString:kind];
535 std::string nativeStreamId = [NSString stdStringForString:streamId];
536 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
537 _peerConnection->CreateSender(nativeKind, nativeStreamId));
538 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300539 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
540 nil;
skvladf3569c82016-04-29 15:30:16 -0700541}
542
skvlad79b4b872016-04-08 17:28:55 -0700543- (NSArray<RTCRtpSender *> *)senders {
544 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
545 _peerConnection->GetSenders());
546 NSMutableArray *senders = [[NSMutableArray alloc] init];
547 for (const auto &nativeSender : nativeSenders) {
548 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300549 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700550 [senders addObject:sender];
551 }
552 return senders;
553}
554
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700555- (NSArray<RTCRtpReceiver *> *)receivers {
556 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
557 _peerConnection->GetReceivers());
558 NSMutableArray *receivers = [[NSMutableArray alloc] init];
559 for (const auto &nativeReceiver : nativeReceivers) {
560 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300561 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700562 [receivers addObject:receiver];
563 }
564 return receivers;
565}
566
Steve Anton8cb344a2018-02-27 15:34:53 -0800567- (NSArray<RTCRtpTransceiver *> *)transceivers {
568 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
569 _peerConnection->GetTransceivers());
570 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
571 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300572 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
573 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800574 [transceivers addObject:transceiver];
575 }
576 return transceivers;
577}
578
hjonf396f602016-02-11 16:19:06 -0800579#pragma mark - Private
580
581+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
582 (RTCSignalingState)state {
583 switch (state) {
584 case RTCSignalingStateStable:
585 return webrtc::PeerConnectionInterface::kStable;
586 case RTCSignalingStateHaveLocalOffer:
587 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
588 case RTCSignalingStateHaveLocalPrAnswer:
589 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
590 case RTCSignalingStateHaveRemoteOffer:
591 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
592 case RTCSignalingStateHaveRemotePrAnswer:
593 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
594 case RTCSignalingStateClosed:
595 return webrtc::PeerConnectionInterface::kClosed;
596 }
597}
598
599+ (RTCSignalingState)signalingStateForNativeState:
600 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
601 switch (nativeState) {
602 case webrtc::PeerConnectionInterface::kStable:
603 return RTCSignalingStateStable;
604 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
605 return RTCSignalingStateHaveLocalOffer;
606 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
607 return RTCSignalingStateHaveLocalPrAnswer;
608 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
609 return RTCSignalingStateHaveRemoteOffer;
610 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
611 return RTCSignalingStateHaveRemotePrAnswer;
612 case webrtc::PeerConnectionInterface::kClosed:
613 return RTCSignalingStateClosed;
614 }
615}
616
617+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
618 switch (state) {
619 case RTCSignalingStateStable:
620 return @"STABLE";
621 case RTCSignalingStateHaveLocalOffer:
622 return @"HAVE_LOCAL_OFFER";
623 case RTCSignalingStateHaveLocalPrAnswer:
624 return @"HAVE_LOCAL_PRANSWER";
625 case RTCSignalingStateHaveRemoteOffer:
626 return @"HAVE_REMOTE_OFFER";
627 case RTCSignalingStateHaveRemotePrAnswer:
628 return @"HAVE_REMOTE_PRANSWER";
629 case RTCSignalingStateClosed:
630 return @"CLOSED";
631 }
632}
633
634+ (webrtc::PeerConnectionInterface::IceConnectionState)
635 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
636 switch (state) {
637 case RTCIceConnectionStateNew:
638 return webrtc::PeerConnectionInterface::kIceConnectionNew;
639 case RTCIceConnectionStateChecking:
640 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
641 case RTCIceConnectionStateConnected:
642 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
643 case RTCIceConnectionStateCompleted:
644 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
645 case RTCIceConnectionStateFailed:
646 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
647 case RTCIceConnectionStateDisconnected:
648 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
649 case RTCIceConnectionStateClosed:
650 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700651 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800652 return webrtc::PeerConnectionInterface::kIceConnectionMax;
653 }
654}
655
656+ (RTCIceConnectionState)iceConnectionStateForNativeState:
657 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
658 switch (nativeState) {
659 case webrtc::PeerConnectionInterface::kIceConnectionNew:
660 return RTCIceConnectionStateNew;
661 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
662 return RTCIceConnectionStateChecking;
663 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
664 return RTCIceConnectionStateConnected;
665 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
666 return RTCIceConnectionStateCompleted;
667 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
668 return RTCIceConnectionStateFailed;
669 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
670 return RTCIceConnectionStateDisconnected;
671 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
672 return RTCIceConnectionStateClosed;
673 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700674 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800675 }
676}
677
678+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
679 switch (state) {
680 case RTCIceConnectionStateNew:
681 return @"NEW";
682 case RTCIceConnectionStateChecking:
683 return @"CHECKING";
684 case RTCIceConnectionStateConnected:
685 return @"CONNECTED";
686 case RTCIceConnectionStateCompleted:
687 return @"COMPLETED";
688 case RTCIceConnectionStateFailed:
689 return @"FAILED";
690 case RTCIceConnectionStateDisconnected:
691 return @"DISCONNECTED";
692 case RTCIceConnectionStateClosed:
693 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700694 case RTCIceConnectionStateCount:
695 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800696 }
697}
698
699+ (webrtc::PeerConnectionInterface::IceGatheringState)
700 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
701 switch (state) {
702 case RTCIceGatheringStateNew:
703 return webrtc::PeerConnectionInterface::kIceGatheringNew;
704 case RTCIceGatheringStateGathering:
705 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
706 case RTCIceGatheringStateComplete:
707 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
708 }
709}
710
711+ (RTCIceGatheringState)iceGatheringStateForNativeState:
712 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
713 switch (nativeState) {
714 case webrtc::PeerConnectionInterface::kIceGatheringNew:
715 return RTCIceGatheringStateNew;
716 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
717 return RTCIceGatheringStateGathering;
718 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
719 return RTCIceGatheringStateComplete;
720 }
721}
722
723+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
724 switch (state) {
725 case RTCIceGatheringStateNew:
726 return @"NEW";
727 case RTCIceGatheringStateGathering:
728 return @"GATHERING";
729 case RTCIceGatheringStateComplete:
730 return @"COMPLETE";
731 }
732}
733
734+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
735 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
736 switch (level) {
737 case RTCStatsOutputLevelStandard:
738 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
739 case RTCStatsOutputLevelDebug:
740 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
741 }
742}
743
hjonf396f602016-02-11 16:19:06 -0800744- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
745 return _peerConnection;
746}
747
748@end