blob: 9a488fdf49423874d3b5e7c2b08a99d6e1fa7ef2 [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"
17#import "RTCMediaConstraints+Private.h"
18#import "RTCMediaStream+Private.h"
19#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070020#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070021#import "RTCRtpSender+Private.h"
22#import "RTCSessionDescription+Private.h"
23#import "RTCStatsReport+Private.h"
24#import "WebRTC/RTCLogging.h"
hjonf396f602016-02-11 16:19:06 -080025
kwibergbfefb032016-05-01 14:53:46 -070026#include <memory>
27
hjonf396f602016-02-11 16:19:06 -080028#include "webrtc/base/checks.h"
29
hjonf396f602016-02-11 16:19:06 -080030NSString * const kRTCPeerConnectionErrorDomain =
31 @"org.webrtc.RTCPeerConnection";
32int const kRTCPeerConnnectionSessionDescriptionError = -1;
33
34namespace webrtc {
35
36class CreateSessionDescriptionObserverAdapter
37 : public CreateSessionDescriptionObserver {
38 public:
39 CreateSessionDescriptionObserverAdapter(
40 void (^completionHandler)(RTCSessionDescription *sessionDescription,
41 NSError *error)) {
42 completion_handler_ = completionHandler;
43 }
44
45 ~CreateSessionDescriptionObserverAdapter() {
46 completion_handler_ = nil;
47 }
48
49 void OnSuccess(SessionDescriptionInterface *desc) override {
50 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070051 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
52 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080053 RTCSessionDescription* session =
54 [[RTCSessionDescription alloc] initWithNativeDescription:
55 description.get()];
56 completion_handler_(session, nil);
57 completion_handler_ = nil;
58 }
59
60 void OnFailure(const std::string& error) override {
61 RTC_DCHECK(completion_handler_);
62 NSString* str = [NSString stringForStdString:error];
63 NSError* err =
64 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
65 code:kRTCPeerConnnectionSessionDescriptionError
66 userInfo:@{ NSLocalizedDescriptionKey : str }];
67 completion_handler_(nil, err);
68 completion_handler_ = nil;
69 }
70
71 private:
72 void (^completion_handler_)
73 (RTCSessionDescription *sessionDescription, NSError *error);
74};
75
76class SetSessionDescriptionObserverAdapter :
77 public SetSessionDescriptionObserver {
78 public:
79 SetSessionDescriptionObserverAdapter(void (^completionHandler)
80 (NSError *error)) {
81 completion_handler_ = completionHandler;
82 }
83
84 ~SetSessionDescriptionObserverAdapter() {
85 completion_handler_ = nil;
86 }
87
88 void OnSuccess() override {
89 RTC_DCHECK(completion_handler_);
90 completion_handler_(nil);
91 completion_handler_ = nil;
92 }
93
94 void OnFailure(const std::string& error) override {
95 RTC_DCHECK(completion_handler_);
96 NSString* str = [NSString stringForStdString:error];
97 NSError* err =
98 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
99 code:kRTCPeerConnnectionSessionDescriptionError
100 userInfo:@{ NSLocalizedDescriptionKey : str }];
101 completion_handler_(err);
102 completion_handler_ = nil;
103 }
104
105 private:
106 void (^completion_handler_)(NSError *error);
107};
108
109PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
110 RTCPeerConnection *peerConnection) {
111 peer_connection_ = peerConnection;
112}
113
114PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
115 peer_connection_ = nil;
116}
117
118void PeerConnectionDelegateAdapter::OnSignalingChange(
119 PeerConnectionInterface::SignalingState new_state) {
120 RTCSignalingState state =
121 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
122 RTCPeerConnection *peer_connection = peer_connection_;
123 [peer_connection.delegate peerConnection:peer_connection
124 didChangeSignalingState:state];
125}
126
127void PeerConnectionDelegateAdapter::OnAddStream(
128 MediaStreamInterface *stream) {
129 RTCMediaStream *mediaStream =
130 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
131 RTCPeerConnection *peer_connection = peer_connection_;
132 [peer_connection.delegate peerConnection:peer_connection
133 didAddStream:mediaStream];
134}
135
136void PeerConnectionDelegateAdapter::OnRemoveStream(
137 MediaStreamInterface *stream) {
138 RTCMediaStream *mediaStream =
139 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
140 RTCPeerConnection *peer_connection = peer_connection_;
141 [peer_connection.delegate peerConnection:peer_connection
142 didRemoveStream:mediaStream];
143}
144
145void PeerConnectionDelegateAdapter::OnDataChannel(
146 DataChannelInterface *data_channel) {
147 RTCDataChannel *dataChannel =
148 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
149 RTCPeerConnection *peer_connection = peer_connection_;
150 [peer_connection.delegate peerConnection:peer_connection
151 didOpenDataChannel:dataChannel];
152}
153
154void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
155 RTCPeerConnection *peer_connection = peer_connection_;
156 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
157}
158
159void PeerConnectionDelegateAdapter::OnIceConnectionChange(
160 PeerConnectionInterface::IceConnectionState new_state) {
161 RTCIceConnectionState state =
162 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
163 RTCPeerConnection *peer_connection = peer_connection_;
164 [peer_connection.delegate peerConnection:peer_connection
165 didChangeIceConnectionState:state];
166}
167
168void PeerConnectionDelegateAdapter::OnIceGatheringChange(
169 PeerConnectionInterface::IceGatheringState new_state) {
170 RTCIceGatheringState state =
171 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
172 RTCPeerConnection *peer_connection = peer_connection_;
173 [peer_connection.delegate peerConnection:peer_connection
174 didChangeIceGatheringState:state];
175}
176
177void PeerConnectionDelegateAdapter::OnIceCandidate(
178 const IceCandidateInterface *candidate) {
179 RTCIceCandidate *iceCandidate =
180 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
181 RTCPeerConnection *peer_connection = peer_connection_;
182 [peer_connection.delegate peerConnection:peer_connection
183 didGenerateIceCandidate:iceCandidate];
184}
185} // namespace webrtc
186
187
188@implementation RTCPeerConnection {
189 NSMutableArray *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700190 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800191 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
192}
193
194@synthesize delegate = _delegate;
195
196- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
197 configuration:(RTCConfiguration *)configuration
198 constraints:(RTCMediaConstraints *)constraints
199 delegate:(id<RTCPeerConnectionDelegate>)delegate {
200 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200201 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700202 [configuration createNativeConfiguration]);
203 if (!config) {
204 return nil;
205 }
hjonf396f602016-02-11 16:19:06 -0800206 if (self = [super init]) {
207 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
kwibergbfefb032016-05-01 14:53:46 -0700208 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints =
hjona2f77982016-03-04 07:09:09 -0800209 constraints.nativeConstraints;
hjonf396f602016-02-11 16:19:06 -0800210 _peerConnection =
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200211 factory.nativeFactory->CreatePeerConnection(*config,
hjona2f77982016-03-04 07:09:09 -0800212 nativeConstraints.get(),
hjonf396f602016-02-11 16:19:06 -0800213 nullptr,
214 nullptr,
215 _observer.get());
216 _localStreams = [[NSMutableArray alloc] init];
217 _delegate = delegate;
218 }
219 return self;
220}
221
222- (NSArray *)localStreams {
223 return [_localStreams copy];
224}
225
226- (RTCSessionDescription *)localDescription {
227 const webrtc::SessionDescriptionInterface *description =
228 _peerConnection->local_description();
229 return description ?
230 [[RTCSessionDescription alloc] initWithNativeDescription:description]
231 : nil;
232}
233
234- (RTCSessionDescription *)remoteDescription {
235 const webrtc::SessionDescriptionInterface *description =
236 _peerConnection->remote_description();
237 return description ?
238 [[RTCSessionDescription alloc] initWithNativeDescription:description]
239 : nil;
240}
241
242- (RTCSignalingState)signalingState {
243 return [[self class]
244 signalingStateForNativeState:_peerConnection->signaling_state()];
245}
246
247- (RTCIceConnectionState)iceConnectionState {
248 return [[self class] iceConnectionStateForNativeState:
249 _peerConnection->ice_connection_state()];
250}
251
252- (RTCIceGatheringState)iceGatheringState {
253 return [[self class] iceGatheringStateForNativeState:
254 _peerConnection->ice_gathering_state()];
255}
256
tkchinaac3eb22016-03-09 21:49:40 -0800257- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200258 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700259 [configuration createNativeConfiguration]);
260 if (!config) {
261 return NO;
262 }
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200263 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800264}
265
hjonf396f602016-02-11 16:19:06 -0800266- (void)close {
267 _peerConnection->Close();
268}
269
270- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700271 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800272 candidate.nativeCandidate);
273 _peerConnection->AddIceCandidate(iceCandidate.get());
274}
275
276- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800277 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800278 RTCLogError(@"Failed to add stream: %@", stream);
279 return;
280 }
281 [_localStreams addObject:stream];
282}
283
284- (void)removeStream:(RTCMediaStream *)stream {
285 _peerConnection->RemoveStream(stream.nativeMediaStream);
286 [_localStreams removeObject:stream];
287}
288
289- (void)offerForConstraints:(RTCMediaConstraints *)constraints
290 completionHandler:
291 (void (^)(RTCSessionDescription *sessionDescription,
292 NSError *error))completionHandler {
293 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
294 observer(new rtc::RefCountedObject
295 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
296 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
297}
298
299- (void)answerForConstraints:(RTCMediaConstraints *)constraints
300 completionHandler:
301 (void (^)(RTCSessionDescription *sessionDescription,
302 NSError *error))completionHandler {
303 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
304 observer(new rtc::RefCountedObject
305 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
306 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
307}
308
309- (void)setLocalDescription:(RTCSessionDescription *)sdp
310 completionHandler:(void (^)(NSError *error))completionHandler {
311 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
312 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
313 completionHandler));
314 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
315}
316
317- (void)setRemoteDescription:(RTCSessionDescription *)sdp
318 completionHandler:(void (^)(NSError *error))completionHandler {
319 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
320 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
321 completionHandler));
322 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
323}
324
skvladf3569c82016-04-29 15:30:16 -0700325- (RTCRtpSender *)senderWithKind:(NSString *)kind
326 streamId:(NSString *)streamId {
327 std::string nativeKind = [NSString stdStringForString:kind];
328 std::string nativeStreamId = [NSString stdStringForString:streamId];
329 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
330 _peerConnection->CreateSender(nativeKind, nativeStreamId));
331 return nativeSender ?
332 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
333 : nil;
334}
335
skvlad79b4b872016-04-08 17:28:55 -0700336- (NSArray<RTCRtpSender *> *)senders {
337 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
338 _peerConnection->GetSenders());
339 NSMutableArray *senders = [[NSMutableArray alloc] init];
340 for (const auto &nativeSender : nativeSenders) {
341 RTCRtpSender *sender =
342 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
343 [senders addObject:sender];
344 }
345 return senders;
346}
347
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700348- (NSArray<RTCRtpReceiver *> *)receivers {
349 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
350 _peerConnection->GetReceivers());
351 NSMutableArray *receivers = [[NSMutableArray alloc] init];
352 for (const auto &nativeReceiver : nativeReceivers) {
353 RTCRtpReceiver *receiver =
354 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
355 [receivers addObject:receiver];
356 }
357 return receivers;
358}
359
hjonf396f602016-02-11 16:19:06 -0800360#pragma mark - Private
361
362+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
363 (RTCSignalingState)state {
364 switch (state) {
365 case RTCSignalingStateStable:
366 return webrtc::PeerConnectionInterface::kStable;
367 case RTCSignalingStateHaveLocalOffer:
368 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
369 case RTCSignalingStateHaveLocalPrAnswer:
370 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
371 case RTCSignalingStateHaveRemoteOffer:
372 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
373 case RTCSignalingStateHaveRemotePrAnswer:
374 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
375 case RTCSignalingStateClosed:
376 return webrtc::PeerConnectionInterface::kClosed;
377 }
378}
379
380+ (RTCSignalingState)signalingStateForNativeState:
381 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
382 switch (nativeState) {
383 case webrtc::PeerConnectionInterface::kStable:
384 return RTCSignalingStateStable;
385 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
386 return RTCSignalingStateHaveLocalOffer;
387 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
388 return RTCSignalingStateHaveLocalPrAnswer;
389 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
390 return RTCSignalingStateHaveRemoteOffer;
391 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
392 return RTCSignalingStateHaveRemotePrAnswer;
393 case webrtc::PeerConnectionInterface::kClosed:
394 return RTCSignalingStateClosed;
395 }
396}
397
398+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
399 switch (state) {
400 case RTCSignalingStateStable:
401 return @"STABLE";
402 case RTCSignalingStateHaveLocalOffer:
403 return @"HAVE_LOCAL_OFFER";
404 case RTCSignalingStateHaveLocalPrAnswer:
405 return @"HAVE_LOCAL_PRANSWER";
406 case RTCSignalingStateHaveRemoteOffer:
407 return @"HAVE_REMOTE_OFFER";
408 case RTCSignalingStateHaveRemotePrAnswer:
409 return @"HAVE_REMOTE_PRANSWER";
410 case RTCSignalingStateClosed:
411 return @"CLOSED";
412 }
413}
414
415+ (webrtc::PeerConnectionInterface::IceConnectionState)
416 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
417 switch (state) {
418 case RTCIceConnectionStateNew:
419 return webrtc::PeerConnectionInterface::kIceConnectionNew;
420 case RTCIceConnectionStateChecking:
421 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
422 case RTCIceConnectionStateConnected:
423 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
424 case RTCIceConnectionStateCompleted:
425 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
426 case RTCIceConnectionStateFailed:
427 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
428 case RTCIceConnectionStateDisconnected:
429 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
430 case RTCIceConnectionStateClosed:
431 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700432 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800433 return webrtc::PeerConnectionInterface::kIceConnectionMax;
434 }
435}
436
437+ (RTCIceConnectionState)iceConnectionStateForNativeState:
438 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
439 switch (nativeState) {
440 case webrtc::PeerConnectionInterface::kIceConnectionNew:
441 return RTCIceConnectionStateNew;
442 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
443 return RTCIceConnectionStateChecking;
444 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
445 return RTCIceConnectionStateConnected;
446 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
447 return RTCIceConnectionStateCompleted;
448 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
449 return RTCIceConnectionStateFailed;
450 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
451 return RTCIceConnectionStateDisconnected;
452 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
453 return RTCIceConnectionStateClosed;
454 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700455 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800456 }
457}
458
459+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
460 switch (state) {
461 case RTCIceConnectionStateNew:
462 return @"NEW";
463 case RTCIceConnectionStateChecking:
464 return @"CHECKING";
465 case RTCIceConnectionStateConnected:
466 return @"CONNECTED";
467 case RTCIceConnectionStateCompleted:
468 return @"COMPLETED";
469 case RTCIceConnectionStateFailed:
470 return @"FAILED";
471 case RTCIceConnectionStateDisconnected:
472 return @"DISCONNECTED";
473 case RTCIceConnectionStateClosed:
474 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700475 case RTCIceConnectionStateCount:
476 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800477 }
478}
479
480+ (webrtc::PeerConnectionInterface::IceGatheringState)
481 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
482 switch (state) {
483 case RTCIceGatheringStateNew:
484 return webrtc::PeerConnectionInterface::kIceGatheringNew;
485 case RTCIceGatheringStateGathering:
486 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
487 case RTCIceGatheringStateComplete:
488 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
489 }
490}
491
492+ (RTCIceGatheringState)iceGatheringStateForNativeState:
493 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
494 switch (nativeState) {
495 case webrtc::PeerConnectionInterface::kIceGatheringNew:
496 return RTCIceGatheringStateNew;
497 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
498 return RTCIceGatheringStateGathering;
499 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
500 return RTCIceGatheringStateComplete;
501 }
502}
503
504+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
505 switch (state) {
506 case RTCIceGatheringStateNew:
507 return @"NEW";
508 case RTCIceGatheringStateGathering:
509 return @"GATHERING";
510 case RTCIceGatheringStateComplete:
511 return @"COMPLETE";
512 }
513}
514
515+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
516 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
517 switch (level) {
518 case RTCStatsOutputLevelStandard:
519 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
520 case RTCStatsOutputLevelDebug:
521 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
522 }
523}
524
525- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
526 return _peerConnection;
527}
528
529@end