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