blob: d0bb39bfb04fe004a8ccf1d74a541d422a10cf4f [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));
451 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
452}
453
454- (void)answerForConstraints:(RTCMediaConstraints *)constraints
455 completionHandler:
456 (void (^)(RTCSessionDescription *sessionDescription,
457 NSError *error))completionHandler {
458 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
459 observer(new rtc::RefCountedObject
460 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
461 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
462}
463
464- (void)setLocalDescription:(RTCSessionDescription *)sdp
465 completionHandler:(void (^)(NSError *error))completionHandler {
466 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
467 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
468 completionHandler));
469 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
470}
471
472- (void)setRemoteDescription:(RTCSessionDescription *)sdp
473 completionHandler:(void (^)(NSError *error))completionHandler {
474 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
475 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
476 completionHandler));
477 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
478}
479
zstein8b476172017-09-05 14:43:03 -0700480- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
481 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
482 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700483 webrtc::PeerConnectionInterface::BitrateParameters params;
484 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200485 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700486 }
487 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200488 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700489 }
490 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200491 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700492 }
493 return _peerConnection->SetBitrate(params).ok();
494}
495
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200496- (void)setBitrateAllocationStrategy:
497 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
498 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
499}
500
ivoc14d5dbe2016-07-04 07:06:55 -0700501- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
502 maxSizeInBytes:(int64_t)maxSizeInBytes {
503 RTC_DCHECK(filePath.length);
504 RTC_DCHECK_GT(maxSizeInBytes, 0);
505 RTC_DCHECK(!_hasStartedRtcEventLog);
506 if (_hasStartedRtcEventLog) {
507 RTCLogError(@"Event logging already started.");
508 return NO;
509 }
510 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
511 S_IRUSR | S_IWUSR);
512 if (fd < 0) {
513 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
514 return NO;
515 }
516 _hasStartedRtcEventLog =
517 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
518 return _hasStartedRtcEventLog;
519}
520
521- (void)stopRtcEventLog {
522 _peerConnection->StopRtcEventLog();
523 _hasStartedRtcEventLog = NO;
524}
525
skvladf3569c82016-04-29 15:30:16 -0700526- (RTCRtpSender *)senderWithKind:(NSString *)kind
527 streamId:(NSString *)streamId {
528 std::string nativeKind = [NSString stdStringForString:kind];
529 std::string nativeStreamId = [NSString stdStringForString:streamId];
530 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
531 _peerConnection->CreateSender(nativeKind, nativeStreamId));
532 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300533 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
534 nil;
skvladf3569c82016-04-29 15:30:16 -0700535}
536
skvlad79b4b872016-04-08 17:28:55 -0700537- (NSArray<RTCRtpSender *> *)senders {
538 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
539 _peerConnection->GetSenders());
540 NSMutableArray *senders = [[NSMutableArray alloc] init];
541 for (const auto &nativeSender : nativeSenders) {
542 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300543 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700544 [senders addObject:sender];
545 }
546 return senders;
547}
548
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700549- (NSArray<RTCRtpReceiver *> *)receivers {
550 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
551 _peerConnection->GetReceivers());
552 NSMutableArray *receivers = [[NSMutableArray alloc] init];
553 for (const auto &nativeReceiver : nativeReceivers) {
554 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300555 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700556 [receivers addObject:receiver];
557 }
558 return receivers;
559}
560
Steve Anton8cb344a2018-02-27 15:34:53 -0800561- (NSArray<RTCRtpTransceiver *> *)transceivers {
562 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
563 _peerConnection->GetTransceivers());
564 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
565 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300566 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
567 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800568 [transceivers addObject:transceiver];
569 }
570 return transceivers;
571}
572
hjonf396f602016-02-11 16:19:06 -0800573#pragma mark - Private
574
575+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
576 (RTCSignalingState)state {
577 switch (state) {
578 case RTCSignalingStateStable:
579 return webrtc::PeerConnectionInterface::kStable;
580 case RTCSignalingStateHaveLocalOffer:
581 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
582 case RTCSignalingStateHaveLocalPrAnswer:
583 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
584 case RTCSignalingStateHaveRemoteOffer:
585 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
586 case RTCSignalingStateHaveRemotePrAnswer:
587 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
588 case RTCSignalingStateClosed:
589 return webrtc::PeerConnectionInterface::kClosed;
590 }
591}
592
593+ (RTCSignalingState)signalingStateForNativeState:
594 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
595 switch (nativeState) {
596 case webrtc::PeerConnectionInterface::kStable:
597 return RTCSignalingStateStable;
598 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
599 return RTCSignalingStateHaveLocalOffer;
600 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
601 return RTCSignalingStateHaveLocalPrAnswer;
602 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
603 return RTCSignalingStateHaveRemoteOffer;
604 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
605 return RTCSignalingStateHaveRemotePrAnswer;
606 case webrtc::PeerConnectionInterface::kClosed:
607 return RTCSignalingStateClosed;
608 }
609}
610
611+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
612 switch (state) {
613 case RTCSignalingStateStable:
614 return @"STABLE";
615 case RTCSignalingStateHaveLocalOffer:
616 return @"HAVE_LOCAL_OFFER";
617 case RTCSignalingStateHaveLocalPrAnswer:
618 return @"HAVE_LOCAL_PRANSWER";
619 case RTCSignalingStateHaveRemoteOffer:
620 return @"HAVE_REMOTE_OFFER";
621 case RTCSignalingStateHaveRemotePrAnswer:
622 return @"HAVE_REMOTE_PRANSWER";
623 case RTCSignalingStateClosed:
624 return @"CLOSED";
625 }
626}
627
628+ (webrtc::PeerConnectionInterface::IceConnectionState)
629 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
630 switch (state) {
631 case RTCIceConnectionStateNew:
632 return webrtc::PeerConnectionInterface::kIceConnectionNew;
633 case RTCIceConnectionStateChecking:
634 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
635 case RTCIceConnectionStateConnected:
636 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
637 case RTCIceConnectionStateCompleted:
638 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
639 case RTCIceConnectionStateFailed:
640 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
641 case RTCIceConnectionStateDisconnected:
642 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
643 case RTCIceConnectionStateClosed:
644 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700645 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800646 return webrtc::PeerConnectionInterface::kIceConnectionMax;
647 }
648}
649
650+ (RTCIceConnectionState)iceConnectionStateForNativeState:
651 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
652 switch (nativeState) {
653 case webrtc::PeerConnectionInterface::kIceConnectionNew:
654 return RTCIceConnectionStateNew;
655 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
656 return RTCIceConnectionStateChecking;
657 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
658 return RTCIceConnectionStateConnected;
659 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
660 return RTCIceConnectionStateCompleted;
661 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
662 return RTCIceConnectionStateFailed;
663 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
664 return RTCIceConnectionStateDisconnected;
665 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
666 return RTCIceConnectionStateClosed;
667 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700668 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800669 }
670}
671
672+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
673 switch (state) {
674 case RTCIceConnectionStateNew:
675 return @"NEW";
676 case RTCIceConnectionStateChecking:
677 return @"CHECKING";
678 case RTCIceConnectionStateConnected:
679 return @"CONNECTED";
680 case RTCIceConnectionStateCompleted:
681 return @"COMPLETED";
682 case RTCIceConnectionStateFailed:
683 return @"FAILED";
684 case RTCIceConnectionStateDisconnected:
685 return @"DISCONNECTED";
686 case RTCIceConnectionStateClosed:
687 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700688 case RTCIceConnectionStateCount:
689 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800690 }
691}
692
693+ (webrtc::PeerConnectionInterface::IceGatheringState)
694 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
695 switch (state) {
696 case RTCIceGatheringStateNew:
697 return webrtc::PeerConnectionInterface::kIceGatheringNew;
698 case RTCIceGatheringStateGathering:
699 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
700 case RTCIceGatheringStateComplete:
701 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
702 }
703}
704
705+ (RTCIceGatheringState)iceGatheringStateForNativeState:
706 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
707 switch (nativeState) {
708 case webrtc::PeerConnectionInterface::kIceGatheringNew:
709 return RTCIceGatheringStateNew;
710 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
711 return RTCIceGatheringStateGathering;
712 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
713 return RTCIceGatheringStateComplete;
714 }
715}
716
717+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
718 switch (state) {
719 case RTCIceGatheringStateNew:
720 return @"NEW";
721 case RTCIceGatheringStateGathering:
722 return @"GATHERING";
723 case RTCIceGatheringStateComplete:
724 return @"COMPLETE";
725 }
726}
727
728+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
729 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
730 switch (level) {
731 case RTCStatsOutputLevelStandard:
732 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
733 case RTCStatsOutputLevelDebug:
734 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
735 }
736}
737
hjonf396f602016-02-11 16:19:06 -0800738- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
739 return _peerConnection;
740}
741
742@end