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