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 "RTCPeerConnection.h" | |
12 | |
13 #import "webrtc/api/objc/RTCPeerConnection+Private.h" | |
14 #import "webrtc/api/objc/RTCConfiguration+Private.h" | |
15 #import "webrtc/api/objc/RTCDataChannel+Private.h" | |
16 #import "webrtc/api/objc/RTCDataChannelConfiguration+Private.h" | |
17 #import "webrtc/api/objc/RTCIceCandidate+Private.h" | |
18 #import "webrtc/api/objc/RTCMediaConstraints+Private.h" | |
19 #import "webrtc/api/objc/RTCMediaStream+Private.h" | |
20 #import "webrtc/api/objc/RTCMediaStreamTrack+Private.h" | |
21 #import "webrtc/api/objc/RTCPeerConnectionFactory+Private.h" | |
22 #import "webrtc/api/objc/RTCPeerConnectionObserver.h" | |
23 #import "webrtc/api/objc/RTCSessionDescription+Private.h" | |
24 #import "webrtc/api/objc/RTCStatsReport+Private.h" | |
25 #import "webrtc/base/objc/NSString+StdString.h" | |
26 | |
27 NSString* const kRTCSessionDescriptionDelegateErrorDomain = @"RTCSDPError"; | |
tkchin_webrtc
2016/02/01 10:00:02
Should be kRTCPeerConnectionErrorDomain that's ext
hjon_webrtc
2016/02/04 00:58:37
Done.
| |
28 int const kRTCSessionDescriptionDelegateErrorCode = -1; | |
29 | |
30 namespace webrtc { | |
31 | |
32 class RTCCreateSessionDescriptionObserver | |
tkchin_webrtc
2016/02/01 10:00:01
following our previous precedence, let's not add R
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
33 : public CreateSessionDescriptionObserver { | |
34 public: | |
35 RTCCreateSessionDescriptionObserver( | |
36 RTCPeerConnection *peerConnection, | |
37 void (^completionHandler) | |
38 (RTCSessionDescription *sessionDescription, NSError *error)) { | |
39 peerConnection_ = peerConnection; | |
tkchin_webrtc
2016/02/01 10:00:02
doco why we need to keep a peer_connection strong
tkchin_webrtc
2016/02/01 10:00:02
c++ style: peer_connection_ (or peerconnection_),
hjon_webrtc
2016/02/04 00:58:37
Done.
hjon_webrtc
2016/02/04 00:58:38
Whoops, looks like this is a case of me not paying
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
40 completionHandler_ = completionHandler; | |
41 } | |
42 | |
43 void OnSuccess(SessionDescriptionInterface *desc) override { | |
tkchin_webrtc
2016/02/01 10:00:01
for sanity, explicitly set ivars to nil in dtor
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
44 RTCSessionDescription *session = | |
45 [[RTCSessionDescription alloc] initWithNativeDescription:desc]; | |
46 if (completionHandler_) { | |
47 completionHandler_(session, nil); | |
48 } | |
49 delete desc; | |
tkchin_webrtc
2016/02/01 10:00:01
use a scoped_ptr instead of explicitly calling del
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
50 } | |
51 | |
52 void OnFailure(const std::string& error) override { | |
53 NSString *str = @(error.c_str()); | |
54 NSError *err = | |
55 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
56 code:kRTCSessionDescriptionDelegateErrorCode | |
57 userInfo:@{@"error" : str}]; | |
tkchin_webrtc
2016/02/01 10:00:02
use NSError standard keys
here maybe you want the
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
58 if (completionHandler_) { | |
59 completionHandler_(nil, err); | |
60 } | |
61 } | |
62 | |
63 private: | |
64 RTCPeerConnection* peerConnection_; | |
65 void (^completionHandler_) | |
66 (RTCSessionDescription *sessionDescription, NSError *error); | |
67 }; | |
68 | |
69 class RTCSetSessionDescriptionObserver : public SetSessionDescriptionObserver { | |
70 public: | |
71 RTCSetSessionDescriptionObserver( | |
72 RTCPeerConnection *peerConnection, | |
73 void (^completionHandler)(NSError *error)) { | |
74 peerConnection_ = peerConnection; | |
75 completionHandler_ = completionHandler; | |
76 } | |
77 | |
78 void OnSuccess() override { | |
79 if (completionHandler_) { | |
80 completionHandler_(nil); | |
81 } | |
82 } | |
83 | |
84 void OnFailure(const std::string& error) override { | |
85 NSString *str = @(error.c_str()); | |
86 NSError *err = | |
87 [NSError errorWithDomain:kRTCSessionDescriptionDelegateErrorDomain | |
88 code:kRTCSessionDescriptionDelegateErrorCode | |
89 userInfo:@{@"error" : str}]; | |
tkchin_webrtc
2016/02/01 10:00:01
ditto
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
90 if (completionHandler_) { | |
91 completionHandler_(err); | |
92 } | |
93 } | |
94 | |
95 private: | |
96 RTCPeerConnection* peerConnection_; | |
97 void (^completionHandler_)(NSError *error); | |
98 }; | |
99 | |
100 class RTCStatsObserver : public StatsObserver { | |
101 public: | |
102 RTCStatsObserver(RTCPeerConnection *peerConnection, | |
103 void (^completionHandler) | |
104 (NSArray<RTCStatsReport *> *stats)) { | |
105 peerConnection_ = peerConnection; | |
106 completionHandler_ = completionHandler; | |
107 } | |
108 | |
109 void OnComplete(const StatsReports& reports) override { | |
110 NSMutableArray *stats = [NSMutableArray arrayWithCapacity:reports.size()]; | |
111 for (const auto* report : reports) { | |
112 RTCStatsReport *statsReport = | |
113 [[RTCStatsReport alloc] initWithNativeReport:*report]; | |
114 [stats addObject:statsReport]; | |
115 } | |
116 if (completionHandler_) { | |
117 completionHandler_(stats); | |
118 } | |
119 } | |
120 | |
121 private: | |
122 RTCPeerConnection *peerConnection_; | |
123 void (^completionHandler_)(NSArray *stats); | |
124 }; | |
125 } | |
126 | |
127 | |
128 @implementation RTCPeerConnection { | |
129 NSMutableArray *_localStreams; | |
130 rtc::scoped_ptr<webrtc::PeerConnectionDelegateAdapter> _observer; | |
131 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection; | |
132 } | |
133 | |
134 @synthesize delegate = _delegate; | |
135 | |
136 - (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory | |
137 configuration:(nullable RTCConfiguration *)configuration | |
138 constraints:(RTCMediaConstraints *)constraints | |
139 delegate:(id<RTCPeerConnectionDelegate>)delegate { | |
140 NSParameterAssert(factory); | |
141 if (self = [super init]) { | |
142 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self)); | |
143 webrtc::PeerConnectionInterface::RTCConfiguration config = | |
144 configuration.nativeConfiguration; | |
tkchin_webrtc
2016/02/01 10:00:02
what happens here if configuration is nil? Will th
hjon_webrtc
2016/02/04 00:58:38
I guess I addressed this in RTCPeerConnection.h, b
| |
145 webrtc::MediaConstraints *nativeConstraints = | |
146 constraints.nativeConstraints.get(); | |
147 _peerConnection = | |
148 factory.nativeFactory->CreatePeerConnection(config, | |
149 nativeConstraints, | |
150 nullptr, | |
151 nullptr, | |
152 _observer.get()); | |
153 _localStreams = [[NSMutableArray alloc] init]; | |
154 _delegate = delegate; | |
155 } | |
156 return self; | |
157 } | |
158 | |
159 - (NSArray *)localStreams { | |
160 return [_localStreams copy]; | |
161 } | |
162 | |
163 - (RTCSessionDescription *)localDescription { | |
164 const webrtc::SessionDescriptionInterface *sdi = | |
tkchin_webrtc
2016/02/01 10:00:02
nit: description not sdi
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
165 _peerConnection->local_description(); | |
166 return sdi ? [[RTCSessionDescription alloc] initWithNativeDescription:sdi] | |
167 : nil; | |
168 } | |
169 | |
170 - (RTCSessionDescription *)remoteDescription { | |
171 const webrtc::SessionDescriptionInterface *sdi = | |
tkchin_webrtc
2016/02/01 10:00:01
ditto
hjon_webrtc
2016/02/04 00:58:37
Done.
| |
172 _peerConnection->remote_description(); | |
173 return sdi ? [[RTCSessionDescription alloc] initWithNativeDescription:sdi] | |
174 : nil; | |
175 } | |
176 | |
177 - (RTCSignalingState)signalingState { | |
178 return [[self class] | |
179 signalingStateForNativeState:_peerConnection->signaling_state()]; | |
180 } | |
181 | |
182 - (RTCIceConnectionState)iceConnectionState { | |
183 return [[self class] iceConnectionStateForNativeState: | |
184 _peerConnection->ice_connection_state()]; | |
185 } | |
186 | |
187 - (RTCIceGatheringState)iceGatheringState { | |
188 return [[self class] iceGatheringStateForNativeState: | |
189 _peerConnection->ice_gathering_state()]; | |
190 } | |
191 | |
192 - (void)close { | |
193 _peerConnection->Close(); | |
194 } | |
195 | |
196 - (void)addIceCandidate:(RTCIceCandidate *)candidate { | |
197 rtc::scoped_ptr<const webrtc::IceCandidateInterface> iceCandidate( | |
198 candidate.nativeCandidate); | |
199 _peerConnection->AddIceCandidate(iceCandidate.get()); | |
200 } | |
201 | |
202 - (void)addStream:(RTCMediaStream *)stream { | |
203 BOOL ret = _peerConnection->AddStream(stream.nativeMediaStream); | |
204 if (!ret) { | |
tkchin_webrtc
2016/02/01 10:00:01
collapse the two lines and log error if failure
hjon_webrtc
2016/02/04 00:58:37
Done.
| |
205 return; | |
206 } | |
207 [_localStreams addObject:stream]; | |
208 } | |
209 | |
210 - (void)removeStream:(RTCMediaStream *)stream { | |
211 _peerConnection->RemoveStream(stream.nativeMediaStream); | |
212 [_localStreams removeObject:stream]; | |
213 } | |
214 | |
215 - (RTCDataChannel *)createDataChannelWithLabel:(NSString *)label | |
216 configuration: | |
217 (RTCDataChannelConfiguration *)configuration { | |
218 std::string labelString = [NSString stdStringForString:label]; | |
219 const webrtc::DataChannelInit nativeInit = | |
220 configuration.nativeDataChannelInit; | |
221 rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel = | |
222 _peerConnection->CreateDataChannel(labelString, | |
223 &nativeInit); | |
224 return [[RTCDataChannel alloc] initWithNativeDataChannel:dataChannel]; | |
225 } | |
226 | |
227 - (void)createOfferWithConstraints:(RTCMediaConstraints *)constraints | |
228 completionHandler: | |
229 (void (^)(RTCSessionDescription *sessionDescription, NSError *error)) | |
230 completionHandler { | |
231 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
232 observer(new rtc::RefCountedObject | |
233 <webrtc::RTCCreateSessionDescriptionObserver>(self, | |
234 completionHandler)); | |
235 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get()); | |
236 } | |
237 | |
238 - (void)createAnswerWithConstraints:(RTCMediaConstraints *)constraints | |
239 completionHandler: | |
240 (void (^)(RTCSessionDescription *sessionDescription, NSError *error)) | |
241 completionHandler { | |
242 rtc::scoped_refptr<webrtc::RTCCreateSessionDescriptionObserver> | |
243 observer(new rtc::RefCountedObject | |
244 <webrtc::RTCCreateSessionDescriptionObserver>(self, | |
245 completionHandler)); | |
246 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get()); | |
247 } | |
248 | |
249 - (void)setLocalDescription:(RTCSessionDescription *)sdp | |
250 completionHandler:(void (^)(NSError *error))completionHandler { | |
251 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
252 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver> | |
253 (self, completionHandler)); | |
254 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription); | |
255 } | |
256 | |
257 - (void)setRemoteDescription:(RTCSessionDescription *)sdp | |
258 completionHandler:(void (^)(NSError *error))completionHandler { | |
259 rtc::scoped_refptr<webrtc::RTCSetSessionDescriptionObserver> observer( | |
260 new rtc::RefCountedObject<webrtc::RTCSetSessionDescriptionObserver> | |
261 (self, completionHandler)); | |
262 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription); | |
263 } | |
264 | |
265 - (void)getStatsForMediaStreamTrack:(RTCMediaStreamTrack *)mediaStreamTrack | |
266 statsOutputLevel:(RTCStatsOutputLevel)statsOutputLevel | |
267 completionHandler: | |
268 (void (^)(NSArray<RTCStatsReport *> *stats))completionHandler { | |
269 rtc::scoped_refptr<webrtc::RTCStatsObserver> observer( | |
270 new rtc::RefCountedObject<webrtc::RTCStatsObserver>(self, | |
271 completionHandler)); | |
272 webrtc::PeerConnectionInterface::StatsOutputLevel nativeOutputLevel = | |
273 [[self class] nativeStatsOutputLevelForLevel:statsOutputLevel]; | |
274 _peerConnection->GetStats( | |
275 observer, mediaStreamTrack.nativeTrack, nativeOutputLevel); | |
276 } | |
277 | |
278 #pragma mark - Private | |
279 | |
280 - (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection { | |
281 return _peerConnection; | |
282 } | |
283 | |
284 + (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: | |
285 (RTCSignalingState)state { | |
286 switch (state) { | |
287 case RTCSignalingStateStable: | |
288 return webrtc::PeerConnectionInterface::kStable; | |
289 case RTCSignalingStateHaveLocalOffer: | |
290 return webrtc::PeerConnectionInterface::kHaveLocalOffer; | |
291 case RTCSignalingStateHaveLocalPrAnswer: | |
292 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer; | |
293 case RTCSignalingStateHaveRemoteOffer: | |
294 return webrtc::PeerConnectionInterface::kHaveRemoteOffer; | |
295 case RTCSignalingStateHaveRemotePrAnswer: | |
296 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer; | |
297 case RTCSignalingStateClosed: | |
298 return webrtc::PeerConnectionInterface::kClosed; | |
299 } | |
300 } | |
301 | |
302 + (RTCSignalingState)signalingStateForNativeState: | |
303 (webrtc::PeerConnectionInterface::SignalingState)nativeState { | |
304 switch (nativeState) { | |
305 case webrtc::PeerConnectionInterface::kStable: | |
306 return RTCSignalingStateStable; | |
307 case webrtc::PeerConnectionInterface::kHaveLocalOffer: | |
308 return RTCSignalingStateHaveLocalOffer; | |
309 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer: | |
310 return RTCSignalingStateHaveLocalPrAnswer; | |
311 case webrtc::PeerConnectionInterface::kHaveRemoteOffer: | |
312 return RTCSignalingStateHaveRemoteOffer; | |
313 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer: | |
314 return RTCSignalingStateHaveRemotePrAnswer; | |
315 case webrtc::PeerConnectionInterface::kClosed: | |
316 return RTCSignalingStateClosed; | |
317 } | |
318 } | |
319 | |
320 + (NSString *)stringForSignalingState:(RTCSignalingState)state { | |
321 switch (state) { | |
322 case RTCSignalingStateStable: | |
323 return @"Stable"; | |
tkchin_webrtc
2016/02/01 10:00:01
nit: all caps
STABLE
HAVE_LOCAL_OFFER
etc.
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
324 case RTCSignalingStateHaveLocalOffer: | |
325 return @"Have local offer"; | |
326 case RTCSignalingStateHaveLocalPrAnswer: | |
327 return @"Have local pranswer"; | |
328 case RTCSignalingStateHaveRemoteOffer: | |
329 return @"Have remote offer"; | |
330 case RTCSignalingStateHaveRemotePrAnswer: | |
331 return @"Have remote pranswer"; | |
332 case RTCSignalingStateClosed: | |
333 return @"Closed"; | |
334 } | |
335 } | |
336 | |
337 + (webrtc::PeerConnectionInterface::IceConnectionState) | |
338 nativeIceConnectionStateForState:(RTCIceConnectionState)state { | |
339 switch (state) { | |
340 case RTCIceConnectionStateNew: | |
341 return webrtc::PeerConnectionInterface::kIceConnectionNew; | |
342 case RTCIceConnectionStateChecking: | |
343 return webrtc::PeerConnectionInterface::kIceConnectionChecking; | |
344 case RTCIceConnectionStateConnected: | |
345 return webrtc::PeerConnectionInterface::kIceConnectionConnected; | |
346 case RTCIceConnectionStateCompleted: | |
347 return webrtc::PeerConnectionInterface::kIceConnectionCompleted; | |
348 case RTCIceConnectionStateFailed: | |
349 return webrtc::PeerConnectionInterface::kIceConnectionFailed; | |
350 case RTCIceConnectionStateDisconnected: | |
351 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected; | |
352 case RTCIceConnectionStateClosed: | |
353 return webrtc::PeerConnectionInterface::kIceConnectionClosed; | |
354 case RTCIceConnectionStateMax: | |
355 return webrtc::PeerConnectionInterface::kIceConnectionMax; | |
356 } | |
357 } | |
358 | |
359 + (RTCIceConnectionState)iceConnectionStateForNativeState: | |
360 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState { | |
361 switch (nativeState) { | |
362 case webrtc::PeerConnectionInterface::kIceConnectionNew: | |
363 return RTCIceConnectionStateNew; | |
364 case webrtc::PeerConnectionInterface::kIceConnectionChecking: | |
365 return RTCIceConnectionStateChecking; | |
366 case webrtc::PeerConnectionInterface::kIceConnectionConnected: | |
367 return RTCIceConnectionStateConnected; | |
368 case webrtc::PeerConnectionInterface::kIceConnectionCompleted: | |
369 return RTCIceConnectionStateCompleted; | |
370 case webrtc::PeerConnectionInterface::kIceConnectionFailed: | |
371 return RTCIceConnectionStateFailed; | |
372 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected: | |
373 return RTCIceConnectionStateDisconnected; | |
374 case webrtc::PeerConnectionInterface::kIceConnectionClosed: | |
375 return RTCIceConnectionStateClosed; | |
376 case webrtc::PeerConnectionInterface::kIceConnectionMax: | |
377 return RTCIceConnectionStateMax; | |
378 } | |
379 } | |
380 | |
381 + (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state { | |
382 switch (state) { | |
383 case RTCIceConnectionStateNew: | |
384 return @"New"; | |
tkchin_webrtc
2016/02/01 10:00:01
ditto all caps
hjon_webrtc
2016/02/04 00:58:37
Done.
| |
385 case RTCIceConnectionStateChecking: | |
386 return @"Checking"; | |
387 case RTCIceConnectionStateConnected: | |
388 return @"Connected"; | |
389 case RTCIceConnectionStateCompleted: | |
390 return @"Completed"; | |
391 case RTCIceConnectionStateFailed: | |
392 return @"Failed"; | |
393 case RTCIceConnectionStateDisconnected: | |
394 return @"Disconnected"; | |
395 case RTCIceConnectionStateClosed: | |
396 return @"Closed"; | |
397 case RTCIceConnectionStateMax: | |
398 return @"Max"; | |
399 } | |
400 } | |
401 | |
402 + (webrtc::PeerConnectionInterface::IceGatheringState) | |
403 nativeIceGatheringStateForState:(RTCIceGatheringState)state { | |
404 switch (state) { | |
405 case RTCIceGatheringStateNew: | |
406 return webrtc::PeerConnectionInterface::kIceGatheringNew; | |
407 case RTCIceGatheringStateGathering: | |
408 return webrtc::PeerConnectionInterface::kIceGatheringGathering; | |
409 case RTCIceGatheringStateComplete: | |
410 return webrtc::PeerConnectionInterface::kIceGatheringComplete; | |
411 } | |
412 } | |
413 | |
414 + (RTCIceGatheringState)iceGatheringStateForNativeState: | |
415 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState { | |
416 switch (nativeState) { | |
417 case webrtc::PeerConnectionInterface::kIceGatheringNew: | |
418 return RTCIceGatheringStateNew; | |
419 case webrtc::PeerConnectionInterface::kIceGatheringGathering: | |
420 return RTCIceGatheringStateGathering; | |
421 case webrtc::PeerConnectionInterface::kIceGatheringComplete: | |
422 return RTCIceGatheringStateComplete; | |
423 } | |
424 } | |
425 | |
426 + (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state { | |
427 switch (state) { | |
428 case RTCIceGatheringStateNew: | |
429 return @"New"; | |
tkchin_webrtc
2016/02/01 10:00:02
ditto all caps
hjon_webrtc
2016/02/04 00:58:38
Done.
| |
430 case RTCIceGatheringStateGathering: | |
431 return @"Gathering"; | |
432 case RTCIceGatheringStateComplete: | |
433 return @"Complete"; | |
434 } | |
435 } | |
436 | |
437 + (webrtc::PeerConnectionInterface::StatsOutputLevel) | |
438 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level { | |
439 switch (level) { | |
440 case RTCStatsOutputLevelStandard: | |
441 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard; | |
442 case RTCStatsOutputLevelDebug: | |
443 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug; | |
444 } | |
445 } | |
446 | |
447 @end | |
OLD | NEW |