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