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