blob: 46ea52a8f643b5bfaa5db49703e2dfe10677330e [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
skvladf3569c82016-04-29 15:30:16 -0700314- (RTCRtpSender *)senderWithKind:(NSString *)kind
315 streamId:(NSString *)streamId {
316 std::string nativeKind = [NSString stdStringForString:kind];
317 std::string nativeStreamId = [NSString stdStringForString:streamId];
318 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
319 _peerConnection->CreateSender(nativeKind, nativeStreamId));
320 return nativeSender ?
321 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
322 : nil;
323}
324
skvlad79b4b872016-04-08 17:28:55 -0700325- (NSArray<RTCRtpSender *> *)senders {
326 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
327 _peerConnection->GetSenders());
328 NSMutableArray *senders = [[NSMutableArray alloc] init];
329 for (const auto &nativeSender : nativeSenders) {
330 RTCRtpSender *sender =
331 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
332 [senders addObject:sender];
333 }
334 return senders;
335}
336
hjonf396f602016-02-11 16:19:06 -0800337#pragma mark - Private
338
339+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
340 (RTCSignalingState)state {
341 switch (state) {
342 case RTCSignalingStateStable:
343 return webrtc::PeerConnectionInterface::kStable;
344 case RTCSignalingStateHaveLocalOffer:
345 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
346 case RTCSignalingStateHaveLocalPrAnswer:
347 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
348 case RTCSignalingStateHaveRemoteOffer:
349 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
350 case RTCSignalingStateHaveRemotePrAnswer:
351 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
352 case RTCSignalingStateClosed:
353 return webrtc::PeerConnectionInterface::kClosed;
354 }
355}
356
357+ (RTCSignalingState)signalingStateForNativeState:
358 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
359 switch (nativeState) {
360 case webrtc::PeerConnectionInterface::kStable:
361 return RTCSignalingStateStable;
362 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
363 return RTCSignalingStateHaveLocalOffer;
364 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
365 return RTCSignalingStateHaveLocalPrAnswer;
366 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
367 return RTCSignalingStateHaveRemoteOffer;
368 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
369 return RTCSignalingStateHaveRemotePrAnswer;
370 case webrtc::PeerConnectionInterface::kClosed:
371 return RTCSignalingStateClosed;
372 }
373}
374
375+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
376 switch (state) {
377 case RTCSignalingStateStable:
378 return @"STABLE";
379 case RTCSignalingStateHaveLocalOffer:
380 return @"HAVE_LOCAL_OFFER";
381 case RTCSignalingStateHaveLocalPrAnswer:
382 return @"HAVE_LOCAL_PRANSWER";
383 case RTCSignalingStateHaveRemoteOffer:
384 return @"HAVE_REMOTE_OFFER";
385 case RTCSignalingStateHaveRemotePrAnswer:
386 return @"HAVE_REMOTE_PRANSWER";
387 case RTCSignalingStateClosed:
388 return @"CLOSED";
389 }
390}
391
392+ (webrtc::PeerConnectionInterface::IceConnectionState)
393 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
394 switch (state) {
395 case RTCIceConnectionStateNew:
396 return webrtc::PeerConnectionInterface::kIceConnectionNew;
397 case RTCIceConnectionStateChecking:
398 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
399 case RTCIceConnectionStateConnected:
400 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
401 case RTCIceConnectionStateCompleted:
402 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
403 case RTCIceConnectionStateFailed:
404 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
405 case RTCIceConnectionStateDisconnected:
406 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
407 case RTCIceConnectionStateClosed:
408 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700409 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800410 return webrtc::PeerConnectionInterface::kIceConnectionMax;
411 }
412}
413
414+ (RTCIceConnectionState)iceConnectionStateForNativeState:
415 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
416 switch (nativeState) {
417 case webrtc::PeerConnectionInterface::kIceConnectionNew:
418 return RTCIceConnectionStateNew;
419 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
420 return RTCIceConnectionStateChecking;
421 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
422 return RTCIceConnectionStateConnected;
423 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
424 return RTCIceConnectionStateCompleted;
425 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
426 return RTCIceConnectionStateFailed;
427 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
428 return RTCIceConnectionStateDisconnected;
429 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
430 return RTCIceConnectionStateClosed;
431 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700432 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800433 }
434}
435
436+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
437 switch (state) {
438 case RTCIceConnectionStateNew:
439 return @"NEW";
440 case RTCIceConnectionStateChecking:
441 return @"CHECKING";
442 case RTCIceConnectionStateConnected:
443 return @"CONNECTED";
444 case RTCIceConnectionStateCompleted:
445 return @"COMPLETED";
446 case RTCIceConnectionStateFailed:
447 return @"FAILED";
448 case RTCIceConnectionStateDisconnected:
449 return @"DISCONNECTED";
450 case RTCIceConnectionStateClosed:
451 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700452 case RTCIceConnectionStateCount:
453 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800454 }
455}
456
457+ (webrtc::PeerConnectionInterface::IceGatheringState)
458 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
459 switch (state) {
460 case RTCIceGatheringStateNew:
461 return webrtc::PeerConnectionInterface::kIceGatheringNew;
462 case RTCIceGatheringStateGathering:
463 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
464 case RTCIceGatheringStateComplete:
465 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
466 }
467}
468
469+ (RTCIceGatheringState)iceGatheringStateForNativeState:
470 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
471 switch (nativeState) {
472 case webrtc::PeerConnectionInterface::kIceGatheringNew:
473 return RTCIceGatheringStateNew;
474 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
475 return RTCIceGatheringStateGathering;
476 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
477 return RTCIceGatheringStateComplete;
478 }
479}
480
481+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
482 switch (state) {
483 case RTCIceGatheringStateNew:
484 return @"NEW";
485 case RTCIceGatheringStateGathering:
486 return @"GATHERING";
487 case RTCIceGatheringStateComplete:
488 return @"COMPLETE";
489 }
490}
491
492+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
493 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
494 switch (level) {
495 case RTCStatsOutputLevelStandard:
496 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
497 case RTCStatsOutputLevelDebug:
498 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
499 }
500}
501
502- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
503 return _peerConnection;
504}
505
506@end