blob: b91a20021532f555f29b1a66164d8463ac4112f0 [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(
202 configuration.nativeConfiguration);
203 if (!config)
204 return nullptr;
hjonf396f602016-02-11 16:19:06 -0800205 if (self = [super init]) {
206 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
kwibergbfefb032016-05-01 14:53:46 -0700207 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints =
hjona2f77982016-03-04 07:09:09 -0800208 constraints.nativeConstraints;
hjonf396f602016-02-11 16:19:06 -0800209 _peerConnection =
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200210 factory.nativeFactory->CreatePeerConnection(*config,
hjona2f77982016-03-04 07:09:09 -0800211 nativeConstraints.get(),
hjonf396f602016-02-11 16:19:06 -0800212 nullptr,
213 nullptr,
214 _observer.get());
215 _localStreams = [[NSMutableArray alloc] init];
216 _delegate = delegate;
217 }
218 return self;
219}
220
221- (NSArray *)localStreams {
222 return [_localStreams copy];
223}
224
225- (RTCSessionDescription *)localDescription {
226 const webrtc::SessionDescriptionInterface *description =
227 _peerConnection->local_description();
228 return description ?
229 [[RTCSessionDescription alloc] initWithNativeDescription:description]
230 : nil;
231}
232
233- (RTCSessionDescription *)remoteDescription {
234 const webrtc::SessionDescriptionInterface *description =
235 _peerConnection->remote_description();
236 return description ?
237 [[RTCSessionDescription alloc] initWithNativeDescription:description]
238 : nil;
239}
240
241- (RTCSignalingState)signalingState {
242 return [[self class]
243 signalingStateForNativeState:_peerConnection->signaling_state()];
244}
245
246- (RTCIceConnectionState)iceConnectionState {
247 return [[self class] iceConnectionStateForNativeState:
248 _peerConnection->ice_connection_state()];
249}
250
251- (RTCIceGatheringState)iceGatheringState {
252 return [[self class] iceGatheringStateForNativeState:
253 _peerConnection->ice_gathering_state()];
254}
255
tkchinaac3eb22016-03-09 21:49:40 -0800256- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200257 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
258 configuration.nativeConfiguration);
259 if (!config)
260 return false;
261 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800262}
263
hjonf396f602016-02-11 16:19:06 -0800264- (void)close {
265 _peerConnection->Close();
266}
267
268- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700269 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800270 candidate.nativeCandidate);
271 _peerConnection->AddIceCandidate(iceCandidate.get());
272}
273
274- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800275 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800276 RTCLogError(@"Failed to add stream: %@", stream);
277 return;
278 }
279 [_localStreams addObject:stream];
280}
281
282- (void)removeStream:(RTCMediaStream *)stream {
283 _peerConnection->RemoveStream(stream.nativeMediaStream);
284 [_localStreams removeObject:stream];
285}
286
287- (void)offerForConstraints:(RTCMediaConstraints *)constraints
288 completionHandler:
289 (void (^)(RTCSessionDescription *sessionDescription,
290 NSError *error))completionHandler {
291 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
292 observer(new rtc::RefCountedObject
293 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
294 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
295}
296
297- (void)answerForConstraints:(RTCMediaConstraints *)constraints
298 completionHandler:
299 (void (^)(RTCSessionDescription *sessionDescription,
300 NSError *error))completionHandler {
301 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
302 observer(new rtc::RefCountedObject
303 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
304 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
305}
306
307- (void)setLocalDescription:(RTCSessionDescription *)sdp
308 completionHandler:(void (^)(NSError *error))completionHandler {
309 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
310 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
311 completionHandler));
312 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
313}
314
315- (void)setRemoteDescription:(RTCSessionDescription *)sdp
316 completionHandler:(void (^)(NSError *error))completionHandler {
317 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
318 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
319 completionHandler));
320 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
321}
322
skvladf3569c82016-04-29 15:30:16 -0700323- (RTCRtpSender *)senderWithKind:(NSString *)kind
324 streamId:(NSString *)streamId {
325 std::string nativeKind = [NSString stdStringForString:kind];
326 std::string nativeStreamId = [NSString stdStringForString:streamId];
327 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
328 _peerConnection->CreateSender(nativeKind, nativeStreamId));
329 return nativeSender ?
330 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
331 : nil;
332}
333
skvlad79b4b872016-04-08 17:28:55 -0700334- (NSArray<RTCRtpSender *> *)senders {
335 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
336 _peerConnection->GetSenders());
337 NSMutableArray *senders = [[NSMutableArray alloc] init];
338 for (const auto &nativeSender : nativeSenders) {
339 RTCRtpSender *sender =
340 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
341 [senders addObject:sender];
342 }
343 return senders;
344}
345
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700346- (NSArray<RTCRtpReceiver *> *)receivers {
347 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
348 _peerConnection->GetReceivers());
349 NSMutableArray *receivers = [[NSMutableArray alloc] init];
350 for (const auto &nativeReceiver : nativeReceivers) {
351 RTCRtpReceiver *receiver =
352 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
353 [receivers addObject:receiver];
354 }
355 return receivers;
356}
357
hjonf396f602016-02-11 16:19:06 -0800358#pragma mark - Private
359
360+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
361 (RTCSignalingState)state {
362 switch (state) {
363 case RTCSignalingStateStable:
364 return webrtc::PeerConnectionInterface::kStable;
365 case RTCSignalingStateHaveLocalOffer:
366 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
367 case RTCSignalingStateHaveLocalPrAnswer:
368 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
369 case RTCSignalingStateHaveRemoteOffer:
370 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
371 case RTCSignalingStateHaveRemotePrAnswer:
372 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
373 case RTCSignalingStateClosed:
374 return webrtc::PeerConnectionInterface::kClosed;
375 }
376}
377
378+ (RTCSignalingState)signalingStateForNativeState:
379 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
380 switch (nativeState) {
381 case webrtc::PeerConnectionInterface::kStable:
382 return RTCSignalingStateStable;
383 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
384 return RTCSignalingStateHaveLocalOffer;
385 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
386 return RTCSignalingStateHaveLocalPrAnswer;
387 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
388 return RTCSignalingStateHaveRemoteOffer;
389 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
390 return RTCSignalingStateHaveRemotePrAnswer;
391 case webrtc::PeerConnectionInterface::kClosed:
392 return RTCSignalingStateClosed;
393 }
394}
395
396+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
397 switch (state) {
398 case RTCSignalingStateStable:
399 return @"STABLE";
400 case RTCSignalingStateHaveLocalOffer:
401 return @"HAVE_LOCAL_OFFER";
402 case RTCSignalingStateHaveLocalPrAnswer:
403 return @"HAVE_LOCAL_PRANSWER";
404 case RTCSignalingStateHaveRemoteOffer:
405 return @"HAVE_REMOTE_OFFER";
406 case RTCSignalingStateHaveRemotePrAnswer:
407 return @"HAVE_REMOTE_PRANSWER";
408 case RTCSignalingStateClosed:
409 return @"CLOSED";
410 }
411}
412
413+ (webrtc::PeerConnectionInterface::IceConnectionState)
414 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
415 switch (state) {
416 case RTCIceConnectionStateNew:
417 return webrtc::PeerConnectionInterface::kIceConnectionNew;
418 case RTCIceConnectionStateChecking:
419 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
420 case RTCIceConnectionStateConnected:
421 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
422 case RTCIceConnectionStateCompleted:
423 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
424 case RTCIceConnectionStateFailed:
425 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
426 case RTCIceConnectionStateDisconnected:
427 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
428 case RTCIceConnectionStateClosed:
429 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700430 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800431 return webrtc::PeerConnectionInterface::kIceConnectionMax;
432 }
433}
434
435+ (RTCIceConnectionState)iceConnectionStateForNativeState:
436 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
437 switch (nativeState) {
438 case webrtc::PeerConnectionInterface::kIceConnectionNew:
439 return RTCIceConnectionStateNew;
440 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
441 return RTCIceConnectionStateChecking;
442 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
443 return RTCIceConnectionStateConnected;
444 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
445 return RTCIceConnectionStateCompleted;
446 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
447 return RTCIceConnectionStateFailed;
448 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
449 return RTCIceConnectionStateDisconnected;
450 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
451 return RTCIceConnectionStateClosed;
452 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700453 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800454 }
455}
456
457+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
458 switch (state) {
459 case RTCIceConnectionStateNew:
460 return @"NEW";
461 case RTCIceConnectionStateChecking:
462 return @"CHECKING";
463 case RTCIceConnectionStateConnected:
464 return @"CONNECTED";
465 case RTCIceConnectionStateCompleted:
466 return @"COMPLETED";
467 case RTCIceConnectionStateFailed:
468 return @"FAILED";
469 case RTCIceConnectionStateDisconnected:
470 return @"DISCONNECTED";
471 case RTCIceConnectionStateClosed:
472 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700473 case RTCIceConnectionStateCount:
474 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800475 }
476}
477
478+ (webrtc::PeerConnectionInterface::IceGatheringState)
479 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
480 switch (state) {
481 case RTCIceGatheringStateNew:
482 return webrtc::PeerConnectionInterface::kIceGatheringNew;
483 case RTCIceGatheringStateGathering:
484 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
485 case RTCIceGatheringStateComplete:
486 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
487 }
488}
489
490+ (RTCIceGatheringState)iceGatheringStateForNativeState:
491 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
492 switch (nativeState) {
493 case webrtc::PeerConnectionInterface::kIceGatheringNew:
494 return RTCIceGatheringStateNew;
495 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
496 return RTCIceGatheringStateGathering;
497 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
498 return RTCIceGatheringStateComplete;
499 }
500}
501
502+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
503 switch (state) {
504 case RTCIceGatheringStateNew:
505 return @"NEW";
506 case RTCIceGatheringStateGathering:
507 return @"GATHERING";
508 case RTCIceGatheringStateComplete:
509 return @"COMPLETE";
510 }
511}
512
513+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
514 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
515 switch (level) {
516 case RTCStatsOutputLevelStandard:
517 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
518 case RTCStatsOutputLevelDebug:
519 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
520 }
521}
522
523- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
524 return _peerConnection;
525}
526
527@end